hooks-permission-request-hook
Generate a PermissionRequest hook with auto-approve/deny rules. Use when needing a safer alternative to --dangerouslySkipPermissions tailored to your project stack.
What this skill does
# /hooks:permission-request-hook
Generate a `PermissionRequest` hook that auto-approves safe operations, auto-denies dangerous ones, and passes everything else through for user decision. A safer, project-aware alternative to `--dangerouslySkipPermissions`.
## When to Use This Skill
| Use this skill when... | Use `/hooks:hooks-configuration` instead when... |
|---|---|
| You want auto-approve/deny rules for Claude Code permissions | Configuring other hook types (PreToolUse, Stop, SessionStart) |
| Replacing `--dangerouslySkipPermissions` with targeted rules | Need general hooks knowledge or debugging |
| Setting up project-specific permission automation | Writing entirely custom hook logic from scratch |
| You need a test harness to validate approve/deny behavior | Understanding hook lifecycle events |
### Auto Mode vs `PermissionRequest` Hook
Auto mode (Claude Code 2.1.83+) routes most approve/deny decisions through a classifier model. It overlaps with — but does not replace — a `PermissionRequest` hook. Choose this skill when you need any of:
- **Deterministic, auditable rules** — the classifier's probabilistic answer is unsuitable for compliance contexts
- **Project-specific deny lists** that go beyond the default trust set
- **Hard 0% false-positive guarantees** for specific commands (the hook is exact, the classifier is not)
- **Pre-approve narrow patterns** so they skip the classifier round-trip and avoid latency/token cost
Hooks coexist with auto mode — they fire alongside the classifier. See `.claude/rules/auto-mode.md` for the full auto-mode model and how it interacts with allow rules and subagents.
## Context
Detect project stack:
- Lockfiles: !`find . -maxdepth 1 \( -name 'package-lock.json' -o -name 'yarn.lock' -o -name 'pnpm-lock.yaml' -o -name 'bun.lockb' -o -name 'poetry.lock' -o -name 'uv.lock' -o -name 'Cargo.lock' -o -name 'go.sum' -o -name 'Gemfile.lock' \)`
- Project files: !`find . -maxdepth 1 \( -name 'package.json' -o -name 'pyproject.toml' -o -name 'requirements.txt' -o -name 'Cargo.toml' -o -name 'go.mod' -o -name 'Gemfile' \)`
- Existing settings: !`find .claude -maxdepth 1 -name 'settings.json' -type f`
- Existing hooks dir: !`find . -maxdepth 2 -type d -name 'scripts'`
- jq available: !`jq --version`
- Existing PermissionRequest hooks: !`jq -r '.hooks.PermissionRequest // empty' .claude/settings.json`
## Parameters
Parse these from `$ARGUMENTS`:
| Flag | Default | Description |
|---|---|---|
| `--strict` | off | Deny unrecognized Bash commands by default instead of passing through to user |
| `--category <name>` | all | Include only specific rule categories. Repeatable. Values: `git`, `test`, `lint`, `build`, `gh`, `deny` |
## Execution
Execute this workflow:
### Step 1: Detect project stack
Identify languages and tooling from the context above.
**Language detection:**
| File Present | Language | Package Manager (from lockfile) |
|---|---|---|
| `package.json` | Node.js | npm (`package-lock.json`), yarn (`yarn.lock`), pnpm (`pnpm-lock.yaml`), bun (`bun.lockb`) |
| `pyproject.toml` / `requirements.txt` | Python | poetry (`poetry.lock`), uv (`uv.lock`), pip (fallback) |
| `Cargo.toml` | Rust | cargo |
| `go.mod` | Go | go modules |
| `Gemfile` | Ruby | bundler |
Report detected stack to user before generating.
### Step 2: Generate the hook script
Create the script at `scripts/permission-request.sh` (or `.claude/hooks/permission-request.sh` if no `scripts/` directory exists).
Use the **Script Template** from [REFERENCE.md](REFERENCE.md). Adapt it by:
1. Including only sections for detected languages (remove `{{ if ... }}` markers)
2. Including only selected categories if `--category` flags were provided
3. Removing all template comments (`{{ ... }}`)
4. If `--strict` is set, include the strict mode catch-all deny at the end
### Step 3: Generate the test script
Create `scripts/test-permission-hook.sh` (or `.claude/hooks/test-permission-hook.sh` to match the hook location).
Use the **Test Script Specification** from [REFERENCE.md](REFERENCE.md). Include test cases only for detected stacks and selected categories. Remove all `{{ ... }}` template markers.
### Step 4: Configure `.claude/settings.json`
Read existing `.claude/settings.json` if it exists. **Merge** the PermissionRequest hook — preserve all existing configuration.
If a `PermissionRequest` hook already exists, ask the user whether to:
- **Replace** the existing PermissionRequest hook
- **Add alongside** the existing hook (both will run)
- **Abort** and keep existing configuration
Configuration to merge:
```json
{
"hooks": {
"PermissionRequest": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash \"$CLAUDE_PROJECT_DIR/scripts/permission-request.sh\"",
"timeout": 10
}
]
}
]
}
}
```
Use `timeout: 10` (10 seconds). Use empty matcher `""` to match all tools. Adjust path if script is in `.claude/hooks/` instead of `scripts/`.
### Step 5: Finalize
1. Make both scripts executable: `chmod +x <hook-path> <test-path>`
2. Create `.claude/` directory if needed for settings.json
3. Run the test script to verify all test cases pass
4. Report summary:
- List files created/modified
- Show number of approve rules, deny rules
- Show test results (pass/fail count)
## Post-Actions
After generating the hook:
1. Suggest committing the new files:
```
scripts/permission-request.sh
scripts/test-permission-hook.sh
.claude/settings.json
```
2. If `--strict` was NOT used, mention the flag for environments where unknown commands should be denied
3. Explain how to add custom rules — edit the APPROVE/DENY sections of the generated script
4. Remind about `CLAUDE_HOOKS_DISABLE_PERMISSION_REQUEST=1` to toggle the hook off temporarily
5. Note that empty matcher `""` catches all tools; suggest narrowing to `"Bash"` if only Bash commands need filtering
## PermissionRequest Schema
### Input (via stdin)
| Field | Type | Description |
|---|---|---|
| `session_id` | string | Current session ID |
| `tool_name` | string | Tool being invoked (`Bash`, `Write`, `Edit`, `Read`, etc.) |
| `tool_input` | object | Tool-specific input (`.command` for Bash, `.file_path` for Write/Edit) |
| `permission_type` | string | Always `"tool_use"` |
| `description` | string | Human-readable description of the operation |
### Output (via stdout)
| Decision | JSON | Effect |
|---|---|---|
| Approve | `{"decision":"approve","reason":"..."}` | Tool runs without user prompt |
| Deny | `{"decision":"deny","reason":"..."}` | Tool blocked, reason shown to Claude |
| Passthrough | Exit 0 with no output | User prompted as normal |
## Agentic Optimizations
| Context | Approach |
|---|---|
| Quick setup, all categories | `/hooks:permission-request-hook` |
| Strict mode (deny unknown commands) | `/hooks:permission-request-hook --strict` |
| Only git and test rules | `/hooks:permission-request-hook --category git --category test` |
| Only deny rules (block dangerous ops) | `/hooks:permission-request-hook --category deny` |
| Test the hook manually | `echo '{"tool_name":"Bash","tool_input":{"command":"git status"}}' \| bash scripts/permission-request.sh` |
| Disable hook temporarily | `CLAUDE_HOOKS_DISABLE_PERMISSION_REQUEST=1` |
## Quick Reference
| Item | Value |
|---|---|
| Hook event | `PermissionRequest` |
| Script location | `scripts/permission-request.sh` or `.claude/hooks/permission-request.sh` |
| Test script | `scripts/test-permission-hook.sh` |
| Settings location | `.claude/settings.json` |
| Timeout | 10 seconds |
| Matcher | `""` (all tools) |
| Toggle | `CLAUDE_HOOKS_DISABLE_PERMISSION_REQUEST=1` |
| Decisions | approve, deny, passthrough (no output) |
| Categories | `git`, `test`, `lint`, `build`, `gh`, `deny` |
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.