Pushary

Claude Code hooks,
from PreToolUse to Stop.

Claude Code hooks are shell commands Claude Code runs at defined points in its loop, configured in settings.json. The most useful are PreToolUse to inspect or block a tool call before it runs, PostToolUse to react after, and Stop or Notification to fire when Claude finishes or needs input. Hooks are how you gate risky actions and get notified without watching the terminal.

99.9%Delivered
Hacker NewsFeatured on Hacker News
3-4xvs Email

A settings.json with two hooks

Hooks live under the hooks key. A PreToolUse hook matches a tool by name and runs a command before it fires. A Stop hook runs when the agent finishes.

~/.claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command", "command": "pushary-hook" }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          { "type": "command", "command": "pushary-hook --notify \"Claude finished\"" }
        ]
      }
    ]
  }
}

The hook events and what each is for

Each event fires at a different point in the loop. Pick the one that matches when you want your command to run.

EventWhat it is for
PreToolUse
Runs before a tool call. Inspect the tool and its input, then allow, block, or ask. This is where you gate risky commands and edits.
PostToolUse
Runs after a tool finishes. React to what happened: lint the file that was edited, log the command, or feed a follow-up note back to the model.
Notification
Fires when Claude Code sends a notification, such as needing permission or sitting idle waiting for your input. Good for a push when the agent is blocked.
Stop
Fires when the main agent finishes responding. Use it to push a done alert so you do not have to watch the terminal.
SubagentStop
Fires when a subagent spawned by the Task tool finishes. Use it to track parallel work without waiting on the whole run.

Exit codes decide what happens

A PreToolUse hook controls a tool call through its exit code, or through structured JSON on stdout for finer control.

exit 2

Blocks the tool call and feeds whatever the hook printed to stderr back to the model as the reason.

exit 0

Allows the tool call to proceed. Anything on stdout is shown in the transcript.

JSON

Print hookSpecificOutput with permissionDecision allow, deny, or ask for structured control.

PreToolUse stdout
{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "Reading .env is blocked by policy."
  }
}

How Pushary uses hooks

Pushary is a Claude Code hook you install with one command. It turns PreToolUse into a phone approval and Stop into a done alert.

PreToolUse waits for your approval

A risky shell command or edit runs the hook, which sends a push and holds the call until you approve or deny from your phone.

Stop pushes a done alert

When Claude finishes, the Stop hook pushes a notification so you can walk away from the terminal and still know the moment it lands.

One command

npx @pushary/agent-hooks setup

Writes the PreToolUse and Stop hooks into your Claude Code settings.json. No manual JSON editing.

Put your hooks to work.

Gate risky tool calls and get a push when Claude finishes. Set up in two minutes.

Claude Code hooks questions

What exit code must a PreToolUse hook return to block a tool call?

Exit code 2. When a PreToolUse hook exits with code 2, Claude Code blocks the tool call and feeds whatever the hook printed to stderr back to the model as the reason. Exit 0 allows the call to proceed. For structured control you can instead exit 0 and print hookSpecificOutput JSON with permissionDecision set to allow, deny, or ask.

What are Claude Code hooks?

Claude Code hooks are shell commands Claude Code runs at defined points in its loop, configured in settings.json. The most useful are PreToolUse to inspect or block a tool call before it runs, PostToolUse to react after, and Stop or Notification to fire when Claude finishes or needs input. Hooks are how you gate risky actions and get notified without watching the terminal.

How do I get a notification when Claude Code finishes?

Add a Stop hook in settings.json that runs a command when the agent finishes responding. Pushary ships a hook you install with one command, so a push lands on your phone the moment Claude is done. A Notification hook covers the other case: it fires when Claude is idle and waiting on your input.

Can a hook stop Claude from reading .env files?

Yes. Add a PreToolUse hook that matches the file-reading tools, checks the path in its input, and exits with code 2 when the path is a .env file. The tool call is blocked and the stderr message explains why to the model. You can also return permissionDecision deny in hookSpecificOutput JSON for the same effect.