- name
- cpv-add-hook
- description
- Add a new hook entry to hooks/hooks.json in an existing plugin (idempotent — skips duplicate entries; cross-platform-aware). Use when adding a new event-handler that must run identically on Linux/macOS/Windows. Used dynamically via cpv-the-skills-menu (TRDD-478d9687).
- when_to_use
- When the cpv-main-menu user picks Create → Add hook to existing plugin, or any flow needs to append a new event-handler entry to hooks/hooks.json with cross-platform-safe command
- user-invocable
- false
# cpv-add-hook
## Overview
Adds a new hook entry to a plugin's `hooks/hooks.json`. The scaffold is idempotent — re-running with the same event+command is a no-op. The new hook command MUST be cross-platform: prefer Python or Node.js delegation. Bash-only constructs (`set -euo pipefail`, `[[ ]]`, `$(<file)`, process substitution, brace expansion) will trigger `validate_hook` MAJOR findings. Loaded dynamically via cpv-the-skills-menu, reached via the Create → Add hook menu branch.
## Prerequisites
- `uv` on PATH
- Target plugin path with `.claude-plugin/plugin.json`
- A valid hook event name (see "Valid event names" below)
- A cross-platform command string (delegate to Python/Node, NOT bash-isms)
## Instructions
1. Pick a valid hook event name from the canonical list.
2. Write the command as a Python or Node delegation. `add_component.py` writes the command verbatim — it does NOT inspect or reject bash-only constructs at write time — so a bash-only command lands in `hooks/hooks.json` and is caught only later by `validate_hook`/`validate_plugin --strict` (step 5) as a MAJOR. Use Python/Node delegation up front to pass that re-validation.
3. Run the underlying `add_component.py --type hook` invocation.
4. The script creates `hooks/hooks.json` if missing or merges into the existing file.
5. Re-validate via `cpv-plugin-validation-skill` to confirm cross-platform compliance.
6. NEVER write runtime state to `${CLAUDE_PLUGIN_ROOT}` (lost on every plugin update). Use `${CLAUDE_PLUGIN_DATA}` instead.
Copy this checklist and track your progress:
- [ ] Event name validated against canonical list
- [ ] Command uses Python/Node delegation (no bash-isms)
- [ ] `add_component.py --type hook` executed
- [ ] `hooks/hooks.json` updated or created
- [ ] `validate_plugin --strict` re-run
## Output
- A new entry in `hooks/hooks.json` keyed by event name.
- Identical entries (same event + same command) are skipped — re-runs are no-ops.
- The file is created if missing; existing entries are preserved.
## Error Handling
| Error | Resolution |
|-------|------------|
| MAJOR: bash-only constructs | Convert command to Python/Node delegation |
| MINOR: POSIX-only tool (jq, sed, awk) | Replace with Python equivalent (json, re.sub, list comprehension) |
| Hook never fires | Check event name spelling; restart Claude Code (plugin hooks pick up on plugin reload) |
| State lost between sessions | Move runtime state writes from `${CLAUDE_PLUGIN_ROOT}` to `${CLAUDE_PLUGIN_DATA}` |
## Examples
```bash
# Cross-platform Python delegation (recommended)
uv run "${CLAUDE_PLUGIN_ROOT}/scripts/add_component.py" /path/to/my-plugin \
--type hook --event PostToolUse \
--command 'python3 "${CLAUDE_PLUGIN_ROOT}/scripts/post_tool.py"'
# Cross-platform Node delegation
uv run "${CLAUDE_PLUGIN_ROOT}/scripts/add_component.py" /path/to/my-plugin \
--type hook --event SessionStart \
--command 'node "${CLAUDE_PLUGIN_ROOT}/scripts/init.js"'
```
### Valid event names
PreToolUse, PostToolUse, PostToolUseFailure, PostToolBatch, PermissionRequest, PermissionDenied, UserPromptSubmit, UserPromptExpansion, Notification, Stop, StopFailure, SubagentStop, SubagentStart, SessionStart, SessionEnd, PreCompact, PostCompact, TeammateIdle, TaskCompleted, TaskCreated, ConfigChange, WorktreeCreate, WorktreeRemove, InstructionsLoaded, Elicitation, ElicitationResult, CwdChanged, FileChanged, MessageDisplay, DirectoryAdded, PreModelSwitch, PostModelSwitch.
### When to use
- Auto-format on file save (PostToolUse on Edit/Write).
- Bootstrap a venv on session start (SessionStart with the diff-and-reinstall pattern).
- Capture telemetry without polluting the conversation (Notification writing to `${CLAUDE_PLUGIN_DATA}/log.jsonl`).
## Resources
- `cpv-add-component-to-plugin` skill — multi-purpose scaffold wrapper
- `cpv-plugin-validation-skill` — validate hooks.json cross-platform compliance
- `cpv-canonical-pipeline` skill — pipeline rules around hook design
- `cpv-fix-validation` skill — fix-up recipes for hook errors
GitHubで見る