diff --git a/plugins/explanatory-output-style/hooks/hooks.json b/plugins/explanatory-output-style/hooks/hooks.json index d1fb8a57..32521439 100644 --- a/plugins/explanatory-output-style/hooks/hooks.json +++ b/plugins/explanatory-output-style/hooks/hooks.json @@ -3,6 +3,7 @@ "hooks": { "SessionStart": [ { + "matcher": "*", "hooks": [ { "type": "command", diff --git a/plugins/hookify/hooks/hooks.json b/plugins/hookify/hooks/hooks.json index d65daca7..a246ccf5 100644 --- a/plugins/hookify/hooks/hooks.json +++ b/plugins/hookify/hooks/hooks.json @@ -3,6 +3,7 @@ "hooks": { "PreToolUse": [ { + "matcher": "*", "hooks": [ { "type": "command", @@ -14,6 +15,7 @@ ], "PostToolUse": [ { + "matcher": "*", "hooks": [ { "type": "command", @@ -25,6 +27,7 @@ ], "Stop": [ { + "matcher": "*", "hooks": [ { "type": "command", @@ -36,6 +39,7 @@ ], "UserPromptSubmit": [ { + "matcher": "*", "hooks": [ { "type": "command", diff --git a/plugins/learning-output-style/hooks/hooks.json b/plugins/learning-output-style/hooks/hooks.json index b3ab7ce9..e7f7036c 100644 --- a/plugins/learning-output-style/hooks/hooks.json +++ b/plugins/learning-output-style/hooks/hooks.json @@ -3,6 +3,7 @@ "hooks": { "SessionStart": [ { + "matcher": "*", "hooks": [ { "type": "command", diff --git a/plugins/plugin-dev/skills/hook-development/scripts/validate-hook-schema.sh b/plugins/plugin-dev/skills/hook-development/scripts/validate-hook-schema.sh index fed0a1f1..da368bad 100755 --- a/plugins/plugin-dev/skills/hook-development/scripts/validate-hook-schema.sh +++ b/plugins/plugin-dev/skills/hook-development/scripts/validate-hook-schema.sh @@ -40,7 +40,27 @@ echo "" echo "Checking root structure..." VALID_EVENTS=("PreToolUse" "PostToolUse" "UserPromptSubmit" "Stop" "SubagentStop" "SessionStart" "SessionEnd" "PreCompact" "Notification") -for event in $(jq -r 'keys[]' "$HOOKS_FILE"); do +# Detect format: plugin format has { description?, hooks: {...} } wrapper +# Settings format has events directly at root level +is_plugin_format=false +if jq -e '.hooks' "$HOOKS_FILE" >/dev/null 2>&1; then + is_plugin_format=true + HOOKS_PATH=".hooks" + echo "Detected plugin format (with 'hooks' wrapper)" + + # Validate allowed root keys for plugin format + for key in $(jq -r 'keys[]' "$HOOKS_FILE"); do + if [ "$key" != "hooks" ] && [ "$key" != "description" ]; then + echo "⚠️ Unknown root key in plugin format: $key (expected: 'hooks', 'description')" + fi + done +else + HOOKS_PATH="." + echo "Detected settings format (events at root)" +fi + +# Validate event types +for event in $(jq -r "$HOOKS_PATH | keys[]" "$HOOKS_FILE"); do found=false for valid_event in "${VALID_EVENTS[@]}"; do if [ "$event" = "$valid_event" ]; then @@ -62,12 +82,12 @@ echo "Validating individual hooks..." error_count=0 warning_count=0 -for event in $(jq -r 'keys[]' "$HOOKS_FILE"); do - hook_count=$(jq -r ".\"$event\" | length" "$HOOKS_FILE") +for event in $(jq -r "$HOOKS_PATH | keys[]" "$HOOKS_FILE"); do + hook_count=$(jq -r "$HOOKS_PATH.\"$event\" | length" "$HOOKS_FILE") for ((i=0; i/dev/null) + +if [ ${#HOOKS_FILES[@]} -eq 0 ]; then + echo "No hooks.json files found" + exit 0 +fi + +echo "Found ${#HOOKS_FILES[@]} hooks.json file(s)" +echo "" + +errors=0 +for hooks_file in "${HOOKS_FILES[@]}"; do + relative_path="${hooks_file#$REPO_ROOT/}" + echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" + echo "📄 $relative_path" + echo "" + + if bash "$VALIDATOR" "$hooks_file"; then + echo "" + else + echo "" + ((errors++)) + fi +done + +echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" +echo "" + +if [ $errors -eq 0 ]; then + echo "✅ All ${#HOOKS_FILES[@]} hooks.json file(s) are valid!" + exit 0 +else + echo "❌ $errors hooks.json file(s) have validation errors" + exit 1 +fi