ClaudeSuperPower
P

PostToolUse (Edit|Write|MultiEdit)

Hook

Fires on

PostToolUsematchingEdit|Write|MultiEdit

Immediately after a tool returns, with its result available.

Where this sits in a session

  1. Session start
  2. Prompt submitted
  3. Prompt expansion
  4. Before tool use
  5. After tool use
  6. Notification
  7. Before compaction
  8. Subagent finished
  9. Turn finished
  10. Session end

Observes onlyEmits messages or context. It never returns a permission decision.

What it runs

Executed automatically when the event fires — no prompt, no confirmation.

command· timeout 15s
${CLAUDE_PLUGIN_ROOT}/scripts/validate-render-yaml-hook.sh

Install it yourself

Paste into .claude/settings.json to run this hook without installing the whole plugin. Adjust the paths to point at your own copy of the scripts.

settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate-render-yaml-hook.sh",
            "timeout": 15
          }
        ],
        "matcher": "Edit|Write|MultiEdit"
      }
    ]
  }
}

Source

Read this before installing — it runs on your machine with your permissions.

#!/usr/bin/env bash
set -uo pipefail

# Claude Code hook: validate render.yaml after Edit/Write/MultiEdit.
#
# Reads the tool-call JSON payload from stdin, extracts tool_input.file_path,
# and runs `render blueprints validate` from that file's directory when the
# touched file is a render.yaml (or render.yml). Exits 0 on no-op so it never
# blocks unrelated edits.

INPUT="$(cat 2>/dev/null || true)"
if [[ -z "$INPUT" ]]; then
  exit 0
fi

extract_file_path() {
  local payload="$1"
  if command -v python3 &>/dev/null; then
    python3 - "$payload" <<'PY' 2>/dev/null
import json, sys
try:
    data = json.loads(sys.argv[1])
except Exception:
    sys.exit(0)
ti = data.get("tool_input") or {}
fp = ti.get("file_path") or ti.get("filePath") or ""
if isinstance(fp, str):
    print(fp)
PY
  else
    printf '%s' "$payload" | sed -n 's/.*"file_path"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -n 1
  fi
}

FILE_PATH="$(extract_file_path "$INPUT")"

if [[ -z "$FILE_PATH" ]]; then
  exit 0
fi

BASENAME="$(basename "$FILE_PATH")"
case "$BASENAME" in
  render.yaml|render.yml) ;;
  *) exit 0 ;;
esac

if ! command -v render &>/dev/null; then
  echo "[render plugin] Render CLI not found. Install it to validate render.yaml:"
  echo "  macOS:  brew install render"
  echo "  Linux:  curl -fsSL https://raw.githubusercontent.com/render-oss/cli/main/bin/install.sh | sh"
  exit 0
fi

DIR="$(dirname "$FILE_PATH")"
if [[ ! -d "$DIR" ]]; then
  exit 0
fi

(cd "$DIR" && render blueprints validate)

Shipped by 1 plugin

Installing any of these installs this hook.

Reviews

Log in to leave a review.

No reviews yet — be the first.

Explore related

Other things in this space — across every part of the ecosystem, not just hooks.