From 3d1d8e101308f1609af34579beadf0188636f3fe Mon Sep 17 00:00:00 2001 From: Ismo Vuorinen Date: Sat, 7 Mar 2026 22:13:43 +0200 Subject: [PATCH] fix(claude): add tool availability guards and fix skill docs Add jq availability checks to hook scripts (block-rules-yml.sh, post-edit-write.sh) and wrap actionlint call in command -v guard, consistent with project rules #2 and #10. Fix validate skill to reflect actual make all pipeline order and note that make test runs separately. --- .claude/hooks/block-rules-yml.sh | 11 +++++-- .claude/hooks/post-edit-write.sh | 49 ++++++++++++++++++-------------- .claude/skills/validate/SKILL.md | 4 ++- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/.claude/hooks/block-rules-yml.sh b/.claude/hooks/block-rules-yml.sh index 2dbb0bc..d289614 100755 --- a/.claude/hooks/block-rules-yml.sh +++ b/.claude/hooks/block-rules-yml.sh @@ -2,6 +2,11 @@ set -eu # Read JSON input from stdin to get the file path +if ! command -v jq >/dev/null 2>&1; then + echo "Error: jq is required but not found" >&2 + exit 1 +fi + INPUT=$(cat) FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.filePath // empty') @@ -10,7 +15,7 @@ if [ -z "$FILE_PATH" ]; then fi case "$FILE_PATH" in - */rules.yml) - echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"rules.yml files are auto-generated. Run make update-validators instead."}}' - ;; +*/rules.yml) + echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"rules.yml files are auto-generated. Run make update-validators instead."}}' + ;; esac diff --git a/.claude/hooks/post-edit-write.sh b/.claude/hooks/post-edit-write.sh index 11fbc87..0efb7c7 100755 --- a/.claude/hooks/post-edit-write.sh +++ b/.claude/hooks/post-edit-write.sh @@ -2,6 +2,11 @@ set -eu # Read JSON input from stdin to get the file path +if ! command -v jq >/dev/null 2>&1; then + echo "Error: jq is required but not found" >&2 + exit 1 +fi + INPUT=$(cat) FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.filePath // empty') @@ -10,30 +15,32 @@ if [ -z "$FILE_PATH" ]; then fi case "$FILE_PATH" in - */rules.yml) - # rules.yml should not be reached here (blocked by PreToolUse), - # but skip formatting just in case - exit 0 - ;; - *.py) - ruff format --quiet "$FILE_PATH" 2>/dev/null || true - ruff check --fix --quiet "$FILE_PATH" 2>/dev/null || true - ;; - *.sh) - shfmt -w "$FILE_PATH" 2>/dev/null || true - shellcheck "$FILE_PATH" 2>&1 || true - ;; - *.yml|*.yaml|*.json) - npx prettier --write "$FILE_PATH" 2>/dev/null || true - ;; - *.md) - npx prettier --write "$FILE_PATH" 2>/dev/null || true - ;; +*/rules.yml) + # rules.yml should not be reached here (blocked by PreToolUse), + # but skip formatting just in case + exit 0 + ;; +*.py) + ruff format --quiet "$FILE_PATH" 2>/dev/null || true + ruff check --fix --quiet "$FILE_PATH" 2>/dev/null || true + ;; +*.sh) + shfmt -w "$FILE_PATH" 2>/dev/null || true + shellcheck "$FILE_PATH" 2>&1 || true + ;; +*.yml | *.yaml | *.json) + npx prettier --write "$FILE_PATH" 2>/dev/null || true + ;; +*.md) + npx prettier --write "$FILE_PATH" 2>/dev/null || true + ;; esac # Run actionlint on action.yml files case "$FILE_PATH" in - */action.yml) +*/action.yml) + if command -v actionlint >/dev/null 2>&1; then actionlint "$FILE_PATH" 2>&1 || true - ;; + fi + ;; esac diff --git a/.claude/skills/validate/SKILL.md b/.claude/skills/validate/SKILL.md index 26818d9..1daeb02 100644 --- a/.claude/skills/validate/SKILL.md +++ b/.claude/skills/validate/SKILL.md @@ -12,7 +12,9 @@ Run the complete validation pipeline: make all ``` -This runs in order: `docs` -> `format` -> `lint` -> `test` +This runs in order: `install-tools` -> `update-validators` -> `docs` -> `update-catalog` -> `format` -> `lint` -> `precommit` + +**Note:** `make test` must be run separately. ## If validation fails