Hook Dashboard
A unified interface for configuring, monitoring, and managing hooks across Git, webhooks, and Claude Code agentic workflows.
Overview
The Hook Dashboard gives you a single pane of glass to manage automation hooks across three paradigms: Git lifecycle hooks, webhook HTTP callbacks, and Claude Code agentic hooks. Whether you're enforcing commit standards, reacting to Stripe payments, or adding deterministic guardrails to an AI coding agent, all your hooks live here.
Inspect Any Hook
Click any hook in the list to open its full detail view — handler code, run metrics, tags, and architecture notes.
Real-Time Metrics
The stats bar tracks total hooks, active count, error state, and cumulative run counts across your entire fleet.
Deterministic Control
Hook execution is guaranteed. Unlike a system prompt instruction, a hook runs every time — no probability involved.
Tagged & Searchable
Filter by category, status, or free-text search across hook names, events, and tags to find exactly what you need.
Core Concepts
Every hook in the dashboard — regardless of category — shares the same three-part structure:
Lifecycle Event
The trigger: pre-commit, payment.succeeded, PostToolUse
Handler
The logic: a shell script, HTTP endpoint URL, or LLM prompt
Outcome Signal
The decision: exit code, HTTP response, or JSON — determines if execution continues
Understanding this three-part pattern makes any hook immediately legible, regardless of what system it lives in.
Key insight: Hooks augment a host system without modifying it. A pre-commit hook doesn't touch Git internals. A webhook handler doesn't modify Stripe. A Claude Code hook doesn't alter the model. They intercept, they observe, and they decide.
Interface Layout
The dashboard is organized into four primary zones:
| Zone | Location | Purpose |
|---|---|---|
| Header | Top bar | App identity and the + New Hook button |
| Stats Bar | Below header | Four live metric cards: total, active, errors, total runs |
| Hook List | Left column | Filters, search, scrollable list of hook cards, and reference panel |
| Detail Panel | Right column | Full inspection of the selected hook — handler, metrics, tags |
Stats Bar
The stats bar at the top of the workspace provides an at-a-glance health summary for your entire hook fleet. It updates immediately whenever you create, delete, activate, or deactivate a hook.
| Metric | What It Shows |
|---|---|
| ⚓ Total Hooks | All hooks registered in the dashboard, regardless of status |
| ▶ Active | Hooks currently enabled and running |
| ⚠ Errors | Hooks that have returned an error state — these need attention |
| ⚡ Total Runs | Cumulative execution count across all hooks |
Browsing Hooks
The hook list on the left shows a scrollable, filterable set of hook cards. Each card displays:
- A status indicator dot (animated green pulse = active, gray = inactive, red = error)
- The hook name
- An inline toggle switch to activate or deactivate without opening the detail view
- Event and handler type badges
- Run count and last run timestamp
Click anywhere on the card body to open the full detail view in the right panel.
Filtering & Search
Three filter controls sit above the hook list and can be combined freely:
Search
The search box filters across hook name, event, and tags simultaneously. It updates the list as you type — no need to press Enter.
Category Filter
Segment the list by hook system:
Status Filter
Filter by hook lifecycle state: All, Active, Inactive, or Error. Use the Error filter to quickly surface hooks that need attention.
Detail Panel
Selecting a hook opens its full profile in the right panel. This is where you inspect, manage, and understand any hook in depth.
Header Section
Shows the hook's name, status dot, and three primary badges: category, event, and handler type. The edit (✏️) and delete (🗑️) action buttons live here.
Metrics Row
Three inline metric cards display the hook's current status, total run count, and last run timestamp.
Handler Block
The handler's content is rendered in a syntax-styled code block. For command hooks this is a shell script. For prompt hooks it's the instruction sent to the model. For agent hooks it's the task description given to the spawned subagent.
Tags
Freeform labels for discovery and grouping. Click a tag in the detail panel to copy it for use in the search box.
Architecture Note
A context-aware explanation at the bottom of the panel describes how this specific hook type works under the hood — different for each category:
- Claude Code hooks: Exit code behavior and how stderr feeds back to the agent
- Webhooks: The two-phase acknowledge-then-process pattern
- Agent hooks: Subagent spawning and deterministic verification
Activate / Deactivate Button
A context-aware button at the bottom of the detail view lets you toggle the hook's status. The label and color update based on current state.
Creating a New Hook
Click + New Hook in the top-right corner to open the creation modal.
Name your hook
Give it a clear, descriptive name. Example: "Block Dangerous Bash Commands". This is required — the form will not submit without it.
Select a category
Choose Git Hooks, Webhooks, or Claude Code Hooks. This choice determines which events are available in the next field.
Pick an event
For Git and Claude hooks, a dropdown populates with valid events for that category. For Webhooks, type the event name directly (e.g., payment.succeeded, order.created).
Choose a handler type
Select command, prompt, or agent. The handler textarea's placeholder updates to guide the appropriate format for each type.
Write the handler
For command hooks: a shell script. For prompt: an instruction to the model. For agent: a task description with success/failure criteria. Webhook handlers should be a valid HTTPS URL.
Add tags (optional)
Type a tag and press Enter or click +. Tags appear as removable pills. Click any tag pill to remove it. Tags make hooks discoverable via the search box.
Click "Create Hook"
The new hook is added to the list, selected automatically, and a confirmation toast appears. The hook starts in Active status.
Webhook validation: Webhook handler fields must begin with http:// or https://. The form will surface a validation error if the URL format is invalid.
Editing & Deleting Hooks
Editing
Open any hook's detail view and click the ✏️ edit button in the top-right of the panel. The edit modal pre-populates all fields with the hook's current configuration. Make your changes and click Save Changes. The detail panel updates immediately.
Deleting
Click the 🗑️ delete button in the detail panel header. A browser confirmation dialog prevents accidental deletion. Confirming removes the hook from the list and clears the detail panel. This action cannot be undone.
Deletion is permanent. There is no undo or recycle bin. Deactivate a hook instead of deleting it if you may need it again.
Toggling Hook Status
You can toggle a hook's active/inactive state in two places:
- From the hook card: Click the toggle switch on the right side of any card in the list. This is the fastest path — no need to open the detail view.
- From the detail panel: Use the Activate Hook / Deactivate Hook button at the bottom of the panel.
Status changes are reflected immediately in the stats bar and the hook's card. Note that toggling from error to active is also supported — useful when you've resolved the underlying issue and want to re-enable the hook.
Git Hooks
Git hooks are executable scripts that fire automatically when lifecycle events occur in a repository. They transform version control from a passive record-keeping tool into an active quality enforcement system.
Client-Side vs. Server-Side
| Type | Where It Runs | Can Be Bypassed? | Primary Use |
|---|---|---|---|
| Client-side | Developer's machine | Yes, by the developer | Linting, test execution, commit formatting |
| Server-side | Remote repository server | No | Governance, CI/CD triggers, security audits |
Example: pre-commit Linter
#!/bin/sh
npm run lint
if [ $? -ne 0 ]; then
echo "Linter failed. Aborting commit."
exit 1
fi
Exit code 0 allows the commit to proceed. Any non-zero exit code aborts the commit. The error message is shown to the developer in their terminal.
Git Hook Event Reference
| Event | Trigger Point | Common Use |
|---|---|---|
pre-commit | Before commit is created | Linting, unit tests |
prepare-commit-msg | Before editor opens | Inject JIRA IDs, templates |
commit-msg | Before commit is finalized | Message format validation |
post-commit | After commit is created | Local notifications, logging |
pre-push | Before git push runs | Final integration tests |
pre-receive | On server during push | Reject non-compliant commits |
post-receive | On server after push | Trigger CI/CD, deployments |
Webhooks
Webhooks are user-defined HTTP callbacks triggered by events in a source system and delivered as HTTP POST requests to a destination URL — typically carrying a JSON payload.
Polling vs. Webhooks
| API Polling | Webhooks | |
|---|---|---|
| Communication model | Client asks "did anything happen?" | Server answers proactively when it does |
| Efficiency | Low — most requests return nothing | High — one request per real event |
| Latency | Depends on poll interval | Near real-time |
| Server load | High | Low |
The Two-Phase Processing Pattern
The most critical implementation detail for webhooks is response timing. If your handler performs slow work synchronously, the provider may time out and retry — creating duplicate events.
Phase 1 (Synchronous)
Receive, validate signature, queue payload, return 200 OK immediately
Phase 2 (Async)
Background worker processes the queue at its own pace, no time pressure
Always respond within the provider timeout. Stripe's timeout is 30 seconds. GitHub's is 10 seconds. Exceeding these without returning 200 triggers automatic retries and may result in your endpoint being flagged or blacklisted.
Claude Code Hooks
Claude Code hooks are the frontier of this dashboard. They attach to specific points in an AI agent's operational lifecycle, providing deterministic control over agent behavior.
The core distinction: A system prompt instruction is probabilistic — the model usually follows it. A hook is a guarantee — it runs every time, regardless of what the model decides.
Claude Code Event Reference
| Event | Trigger Point | Typical Use |
|---|---|---|
SessionStart | New session begins | Inject Git branch, env vars, recent commits |
UserPromptSubmit | Before Claude processes prompt | Safety validation, request enrichment |
PreToolUse | Before a tool executes | Block rm -rf, intercept dangerous patterns |
PostToolUse | After a tool call succeeds | Run Prettier, Black, or other formatters |
Notification | When Claude needs attention | Desktop notifications, Slack alerts |
Stop | Response is complete | Secondary verification, quality checks |
PreCompact | Before context compaction | Persist conversation summary |
Handler Types
Every hook uses one of three handler types. The type determines how the hook's logic executes and what it can do.
Shell Command
Executes a shell script or binary. Fastest and most deterministic. Exit code 0 = pass, exit code 2 = block (stderr feeds back to Claude as an error message).
Best for: Formatters, linters, pattern matching, anything with clear binary logic.
LLM Prompt
Sends a single-turn instruction to a Claude model. Returns a structured JSON allow/deny decision with an explanation.
Best for: Judgment calls that need reasoning — "does this edit violate our security policy?"
Subagent
Spawns a complete Claude subagent with access to tools (file reading, grep, glob). Enables sophisticated verification logic that operates on the full codebase.
Example: "For every new function added, verify a corresponding unit test exists in /tests. Report missing tests as blocking errors." This is not a style check — this is an AI verifying another AI's work.
Choose the simplest handler type that can accomplish the task. Command hooks are faster and cheaper than prompt hooks, which are faster and cheaper than agent hooks. Reserve agent hooks for tasks that genuinely require tool access and multi-step reasoning.
Architecture Reference
The Three Invariants
Regardless of category, a hook's behavior is fully determined by three things:
| Element | Git Example | Webhook Example | Claude Example |
|---|---|---|---|
| Lifecycle Event | pre-commit | payment.succeeded | PostToolUse |
| Handler | Shell script | HTTPS endpoint | Shell / Prompt / Agent |
| Outcome Signal | Exit code | HTTP 200 / 4xx | Exit code / JSON decision |
Exit Code Semantics (Command Hooks)
| Exit Code | Meaning | What Happens |
|---|---|---|
0 | Success | Execution continues normally |
1 | General error | Execution aborted, error shown |
2 | Blocking error | Stderr output fed back to Claude as context for reconsideration |
The Augmentation Principle
Hooks augment without modifying their host system. A pre-commit hook doesn't touch Git internals. A PostToolUse formatter hook doesn't modify the Claude model. A webhook handler doesn't touch Stripe's API. This is why hooks are the essential building block of modular, composable software — they insert behavior without coupling to implementation.
Reference Panel (In-App)
The dashboard includes a built-in reference panel at the bottom of the left column. It has three tabs:
- Git Events — all 7 Git hook events with descriptions
- Claude Events — all 7 Claude Code hook events with descriptions
- Architecture — the three-part hook structure explained inline