Skip to content
Development
Skill

/cc-hooks

Configure Claude Code hooks and narrow enforcement guards. Use when: the caller requests hook installation, repair or policy changes; a hook is not required to use other skills.

From plugin
agentops
43634 skills7 agents1 hook
Install
$ npx -y skills add boshu2/agentops --skill cc-hooks --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/cc-hooks

Context preview

The summary Claude sees to decide when to auto-load this skill.

Configure Claude Code hooks and narrow enforcement guards. Use when: the caller requests hook installation, repair or policy changes; a hook is not required to use other skills.

SKILL.md

cc-hooks.SKILL.md
name: cc-hooks
user-invocable: true
skill_api_version: 1
hexagonal_role: supporting
consumes: []
produces: []
context_rel: []
metadata:
  dependencies: []
  capabilities: [cc_hooks]
  effects: [write_hook_config, append_guardrail_telemetry, write_session_sentinel]
  canonical_status: canonical
  disposition: keep_optional_adapter
  tier: execution
description: 'Configure Claude Code hooks and narrow enforcement guards. Use when: the caller requests hook installation, repair or policy changes; a hook is not required to use other skills.'
practices:
- pragmatic-programmer
output_contract: a hooks block in ~/.claude or project settings.json (matcher + command entries), or a hook script signalling allow/deny/ask via exit codes and hookSpecificOutput JSON; installs write hook config and guard fires append hashed telemetry

Claude Code Hooks

Shell commands that fire at specific points in Claude Code's lifecycle.

Hooks enforce mechanically what prose cannot: a model can reason its way past an instruction, but it cannot reason its way past an exit 2 — which is exactly why every hook must be narrow, silent, and reversible.

Named failure mode — **chatty happy path**: a hook that emits stdout on exit 0 corrupts the tool call it was guarding; silence on success is part of the contract, not a style preference.

Prompt

Add a PreToolUse hook to fleet-router/.claude/settings.json that blocks `git push --force` on the main branch. Keep it silent on exit 0, exit 2 with a message on block, and confirm it fires with a manual test invocation before committing the change.

It's working if

  • The hook script exits `2` with a stderr message when it blocks `git push --force`, and exit `0` with no stdout on the allowed path.
  • `.claude/settings.json` gains one matcher entry for the new hook, alongside the existing hooks list rather than replacing it.
  • A manual test invocation against the new matcher shows the block firing in the transcript, with exit `2` visible, before the change gets committed.
  • The hook inspects only the `PreToolUse` call it guards, keeping every other file untouched.

Constraints

  • Enforcement hooks (the PreToolUse policy dispatcher) ship by DEFAULT: plugin installs auto-wire `hooks/hooks.json`; skill copies and checkouts wire with one command (`scripts/install-hooks.sh`). Operators can disable per host (`/plugin disable`, or remove the settings matchers).
  • Injection hooks (SessionStart/UserPromptSubmit context stuffing) stay dead — the #511 teardown proved delta=0 at 10.35M resident tokens. Never ship one; the hookless-cold-start gate still enforces this.
  • Keep the happy path silent and block only with the event's documented exit/JSON contract because stray stdout can corrupt a tool call.
  • Bound Stop hooks with `stop_hook_active` and scope matchers narrowly to prevent recursion and unrelated-command interception.

<!-- TOC: Quick Start | Events | Blocking | Writing Hooks | Anti-Patterns | References -->

Quick Start

Add to `~/.claude/settings.json` (user) or `.claude/settings.json` (project):

{"hooks":{"PreToolUse":[{"matcher":"Bash","hooks":[{"type":"command","command":"my-validator.sh"}]}]}}

Hook Events

| Event | When | Blocks? | Common Use | |-------|------|---------|------------| | `PreToolUse` | Before tool runs | Yes | Block/modify commands | | `PostToolUse` | After tool succeeds | Feedback | Auto-format, lint | | `PermissionRequest` | Permission dialog | Yes | Auto-approve/deny | | `UserPromptSubmit` | Prompt submitted | Yes | Add context, validate | | `Stop` | Claude finishes | Yes | Force continue | | `SessionStart` | Session begins | No | Load context, set env | | `Notification` | Notifications | No | Desktop alerts |

Full schemas: [HOOK-EVENTS.md](references/HOOK-EVENTS.md)

Matchers

"Bash"              → exact match
"Edit|Write"        → regex OR
"mcp__.*__write"    → MCP tools
"*" or ""           → all tools

Tools: `Bash`, `Read`, `Write`, `Edit`, `Glob`, `Grep`, `Task`, `WebFetch`, `WebSearch`

Exit Codes

| Code | Effect | |------|--------| | 0 | Success - JSON parsed from stdout | | 2 | **Block** - stderr fed to Claude | | Other | Non-blocking error |

Blocking a Tool

**Simple (exit 2):**

echo "Blocked: reason" >&2 && exit 2

**JSON (exit 0):**

{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"Blocked"}}

Decisions: `"allow"` (auto-approve), `"deny"` (block), `"ask"` (show dialog)

Modifying Input

{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow",
  "updatedInput":{"command":"modified-command"}}}

Real-World: DCG + RCH

{"hooks":{"PreToolUse":[{"matcher":"Bash","hooks":[
  {"type":"command","command":"dcg"},
  {"type":"command","command":"rch"}
]}]}}
  • **DCG**: Blocks `git reset --hard`, `rm -rf`, `git push --force`
  • **RCH**: Routes builds to remote workers

Details: [DCG-RCH.md](references/DCG-RCH.md)

Skill-First Coordination Guard (opt-in)

A copy-paste PreToolUse recipe that nudges agents to **load the coordination skill before hand-rolling the `am`/`atm`/`ntm`/`tmux send-keys` CLI**. This recipe auto-installs nothing; you opt in per host (unlike the policy dispatcher, which ships by default).

**Context-budget doctrine for hooks:** hooks are the most powerful enforcement (mechanical, can't be reasoned past) but they pollute context — use sparingly. A hook must be SILENT on the happy path (exit 0, no stdout/stderr), fire ONLY on a real violation (ideally once per session, sentinel-gated), prefer PreToolUse violation-guards over `UserPromptSubmit`/`SessionStart` per-turn injectors, and NEVER emit stray stdout on an exit-0 PreToolUse path (it is parsed as JSON and breaks the tool call). Block via exit 2 + stderr.

The recipe ships both scripts verbatim, a precise head-only matcher (so a `br create --body "...am/atm/ntm..."` never false-fires), th

Read more
Ships withagentops

AgentOps gives Claude Code and Codex reusable instructions, called skills, for investigating code, writing useful tests, and independently reviewing changes.

Get the whole plugin

Other skills on agentops.

cass
Skill

cass

Search agent session logs and cited episodes with CASS. Use when: past prompts, decisions or failures may answer a question; repeated text is not a proven…

@boshu2@boshu2View Skill