ClaudeSuperPower
P

PostToolUse (Edit|MultiEdit|Write)

Hook

Fires on

PostToolUsematchingEdit|MultiEdit|Write

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

Can blockThis hook is able to deny the action or send Claude back to work.

What it runs

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

command· timeout 10s
bash "${CLAUDE_PLUGIN_ROOT}/hooks/check-manifest-edit.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": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/check-manifest-edit.sh\"",
            "timeout": 10
          }
        ],
        "matcher": "Edit|MultiEdit|Write"
      }
    ]
  }
}

Source

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

#!/usr/bin/env bash
# endor_agent_kit_managed=true

if ! command -v python3 >/dev/null 2>&1; then
  exit 0
fi

payload="$(cat)"
HOOK_PAYLOAD="$payload" python3 - "$@" <<'PY' || true
import json
import os
import re
import sys


MANIFEST_RE = re.compile(
    r"(^|/)(package\.json|package-lock\.json|npm-shrinkwrap\.json|pnpm-lock\.yaml|"
    r"yarn\.lock|pyproject\.toml|poetry\.lock|requirements.*\.txt|Pipfile|Pipfile\.lock|"
    r"go\.mod|go\.sum|Cargo\.toml|Cargo\.lock|pom\.xml|build\.gradle|build\.gradle\.kts|"
    r"Gemfile|Gemfile\.lock|composer\.json|composer\.lock)$",
    re.IGNORECASE,
)


def emit(event_name: str, message: str) -> None:
    print(json.dumps({
        "hookSpecificOutput": {
            "hookEventName": event_name,
            "additionalContext": message,
        }
    }, separators=(",", ":")))


try:
    raw = os.environ.get("HOOK_PAYLOAD", "")
    payload = json.loads(raw or "{}")
    if not isinstance(payload, dict):
        raise ValueError("hook payload must be an object")
    default_event = sys.argv[1] if len(sys.argv) > 1 else "PostToolUse"
    event = str(
        payload.get("hook_event_name")
        or payload.get("hookEventName")
        or payload.get("event")
        or default_event
    )
    tool_input = payload.get("tool_input") or payload.get("toolInput") or {}
    if not isinstance(tool_input, dict):
        tool_input = {}
    nested_args = tool_input.get("args") if isinstance(tool_input.get("args"), dict) else {}
    nested_params = tool_input.get("params") if isinstance(tool_input.get("params"), dict) else {}
    modified_files = payload.get("modified_files") or payload.get("modifiedFiles") or []
    if not isinstance(modified_files, list):
        modified_files = []
    candidate_paths = [
        tool_input.get("file_path"),
        tool_input.get("path"),
        nested_args.get("file_path"),
        nested_args.get("path"),
        nested_params.get("file_path"),
        nested_params.get("path"),
        payload.get("file_path"),
        payload.get("path"),
        *modified_files,
    ]
    path = next((str(item) for item in candidate_paths if item), "")
    if not path or not MANIFEST_RE.search(path):
        raise SystemExit(0)
    emit(
        event,
        "Endor Agent Kit manifest advisory: this edit touches a dependency manifest or lockfile. "
        "Use `dependency-decision-helper` for new dependency approval, `package-risk-summary` for known "
        "package-version risk, or `repository-dependency-reviewer` for a repository-level manifest review. "
        "Do not run a scan or mutate Endor state from this hook context."
    )
except Exception:
    pass
PY

exit 0

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.