Skip to content
Documentation
Hook

Hooks

What claude-code-mastery runs automatically, and when. A hook is a command Claude Code fires at a fixed moment, without you asking for it.

From plugin
claude-code-mastery
5582 skills4 commands5 hooks

Claude Code

$ npx -y skills add TheDecipherist/claude-code-mastery --agent claude-code

Where it lives

  • hooks/after-edit.shGitHub
    Read the script
    #!/usr/bin/env bash
    # =============================================================================
    # PostToolUse Hook: After File Edit
    # =============================================================================
    #
    # This hook runs AFTER Claude edits or writes a file.
    # Use it for fast operations like formatting that should run immediately.
    #
    # For heavier checks (tests, full linting), use the end-of-turn (Stop) hook.
    #
    # Usage:
    #   Add to ~/.claude/settings.json:
    #   {
    #     "hooks": {
    #       "PostToolUse": [
    #         {
    #           "matcher": "Edit|Write",
    #           "hooks": [
    #             {
    #               "type": "command",
    #               "command": "~/.claude/hooks/after-edit.sh"
    #             }
    #           ]
    #         }
    #       ]
    #     }
    #   }
    # =============================================================================
    
    set -euo pipefail
    
    # Read JSON input from stdin
    INPUT=$(cat)
    
    # Extract the file path
    FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // empty')
    
    if [[ -z "$FILE_PATH" ]]; then
        exit 0  # No file path, nothing to do
    fi
    
    # Get file extension
    EXTENSION="${FILE_PATH##*.}"
    
    # -----------------------------------------------------------------------------
    # Format based on file type
    # -----------------------------------------------------------------------------
    
    case "$EXTENSION" in
        js|jsx|ts|tsx|json|md|yaml|yml|css|scss|html)
            # Prettier for web files
            if command -v prettier &>/dev/null; then
                prettier --write "$FILE_PATH" 2>/dev/null || true
            fi
            ;;
        
        py)
            # Black for Python
            if command -v black &>/dev/null; then
                black --quiet "$FILE_PATH" 2>/dev/null || true
            fi
            # Ruff for linting
            if command -v ruff &>/dev/null; then
                ruff check --fix --silent "$FILE_PATH" 2>/dev/null || true
            fi
            ;;
        
        go)
            # gofmt for Go
            if command -v gofmt &>/dev/null; then
                gofmt -w "$FILE_PATH" 2>/dev/null || true
            fi
            ;;
        
        rs)
            # rustfmt for Rust
            if command -v rustfmt &>/dev/null; then
                rustfmt "$FILE_PATH" 2>/dev/null || true
            fi
            ;;
        
        sh|bash)
            # shfmt for shell scripts
            if command -v shfmt &>/dev/null; then
                shfmt -w "$FILE_PATH" 2>/dev/null || true
            fi
            ;;
    esac
    
    # Always exit 0 - formatting failures shouldn't block work
    exit 0
    
  • hooks/block-dangerous-commands.shGitHub
    Read the script
    #!/usr/bin/env bash
    # =============================================================================
    # PreToolUse Hook: Block Dangerous Bash Commands
    # =============================================================================
    #
    # This hook runs BEFORE bash commands execute.
    # It blocks destructive patterns like rm -rf, force pushes, etc.
    #
    # Exit codes:
    #   0 = Allow command
    #   2 = Block command (stderr fed back to Claude)
    #
    # Usage:
    #   Add to ~/.claude/settings.json:
    #   {
    #     "hooks": {
    #       "PreToolUse": [
    #         {
    #           "matcher": "Bash",
    #           "hooks": [
    #             {
    #               "type": "command",
    #               "command": "~/.claude/hooks/block-dangerous-commands.sh"
    #             }
    #           ]
    #         }
    #       ]
    #     }
    #   }
    # =============================================================================
    
    set -euo pipefail
    
    # Read JSON input from stdin
    INPUT=$(cat)
    
    # Extract the command using jq
    COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
    
    if [[ -z "$COMMAND" ]]; then
        exit 0  # No command, allow
    fi
    
    # -----------------------------------------------------------------------------
    # Dangerous Patterns
    # -----------------------------------------------------------------------------
    
    # rm -rf with dangerous paths
    if echo "$COMMAND" | grep -qE 'rm\s+(-[a-zA-Z]*r[a-zA-Z]*f|--recursive\s+--force|-rf|-fr)\s+(/|~|\.\.|\$HOME|\$\{HOME\})'; then
        echo "๐Ÿ›‘ BLOCKED: Destructive rm command targeting root, home, or parent directory" >&2
        echo "Command: $COMMAND" >&2
        exit 2
    fi
    
    # rm -rf /* or rm -rf ~/*
    if echo "$COMMAND" | grep -qE 'rm\s+(-[a-zA-Z]*r[a-zA-Z]*f|--recursive\s+--force|-rf|-fr)\s+(/\*|~/\*|/home)'; then
        echo "๐Ÿ›‘ BLOCKED: Destructive rm command with wildcard on sensitive path" >&2
        echo "Command: $COMMAND" >&2
        exit 2
    fi
    
    # Force push to main/master
    if echo "$COMMAND" | grep -qE 'git\s+push\s+.*(-f|--force)\s+.*(main|master|production|release)'; then
        echo "๐Ÿ›‘ BLOCKED: Force push to protected branch" >&2
        echo "Command: $COMMAND" >&2
        echo "Tip: Create a PR instead of force pushing to main/master" >&2
        exit 2
    fi
    
    # chmod 777 (world-writable)
    if echo "$COMMAND" | grep -qE 'chmod\s+(777|a\+rwx)'; then
        echo "โš ๏ธ BLOCKED: Setting world-writable permissions (777)" >&2
        echo "Command: $COMMAND" >&2
        echo "Tip: Use 755 for directories, 644 for files" >&2
        exit 2
    fi
    
    # Piping curl directly to shell (dangerous pattern)
    if echo "$COMMAND" | grep -qE 'curl\s+.*\|\s*(ba)?sh'; then
        echo "โš ๏ธ BLOCKED: Piping curl output directly to shell" >&2
        echo "Command: $COMMAND" >&2
        echo "Tip: Download script first, review it, then execute" >&2
        exit 2
    fi
    
    # wget piped to shell
    if echo "$COMMAND" | grep -qE 'wget\s+.*\|\s*(ba)?sh'; then
        echo "โš ๏ธ BLOCKED: Piping wget output directly to shell" >&2
        echo "Command: $COMMAND" >&2
        exit 2
    fi
    
    # dd writing to disk devices
    if echo "$COMMAND" | grep -qE 'dd\s+.*of=/dev/(sd|hd|nvme|disk)'; then
        echo "๐Ÿ›‘ BLOCKED: dd command writing directly to disk device" >&2
        echo "Command: $COMMAND" >&2
        exit 2
    fi
    
    # mkfs (format disk)
    if echo "$COMMAND" | grep -qE 'mkfs'; then
        echo "๐Ÿ›‘ BLOCKED: mkfs command (disk formatting)" >&2
        echo "Command: $COMMAND" >&2
        exit 2
    fi
    
    # Commands that could exfiltrate data
    if echo "$COMMAND" | grep -qE '(curl|wget|nc|netcat)\s+.*\.(env|pem|key|secret)'; then
        echo "โš ๏ธ BLOCKED: Command appears to exfiltrate sensitive files" >&2
        echo "Command: $COMMAND" >&2
        exit 2
    fi
    
    # Reading .env files via cat/less/head/tail
    if echo "$COMMAND" | grep -qE '(cat|less|head|tail|more|bat)\s+.*\.env'; then
        echo "โš ๏ธ BLOCKED: Reading .env file via $COMMAND" >&2
        echo "Tip: Use environment variables instead of reading .env directly" >&2
        exit 2
    fi
    
    # -----------------------------------------------------------------------------
    # Command is safe, allow it
    # -----------------------------------------------------------------------------
    exit 0
    
  • hooks/block-secrets.pyGitHub
    Read the script
    #!/usr/bin/env python3
    """
    PreToolUse hook to block access to sensitive files.
    
    This hook runs BEFORE Claude can read, edit, or write files.
    Exit code 2 blocks the operation and feeds stderr back to Claude.
    
    Usage:
      Add to ~/.claude/settings.json:
      {
        "hooks": {
          "PreToolUse": [
            {
              "matcher": "Read|Edit|Write",
              "hooks": [
                {
                  "type": "command",
                  "command": "python3 ~/.claude/hooks/block-secrets.py"
                }
              ]
            }
          ]
        }
      }
    
    Why this matters:
      - CLAUDE.md rules are suggestions that Claude can override
      - This hook is deterministic enforcement - it ALWAYS runs
      - Even if Claude is "convinced" to read secrets, this blocks it
    """
    import json
    import sys
    from pathlib import Path
    
    # =============================================================================
    # CONFIGURATION - Customize these patterns for your environment
    # =============================================================================
    
    # Exact filenames to block
    SENSITIVE_FILENAMES = {
        # Environment files
        '.env',
        '.env.local',
        '.env.development',
        '.env.development.local',
        '.env.test',
        '.env.test.local',
        '.env.production',
        '.env.production.local',
        '.env.staging',
        
        # Secrets files
        'secrets.json',
        'secrets.yaml',
        'secrets.yml',
        'secrets.toml',
        '.secrets',
        
        # Credentials
        'credentials.json',
        'credentials.yaml',
        'service-account.json',
        'service_account.json',
        
        # SSH keys
        'id_rsa',
        'id_rsa.pub',
        'id_ed25519',
        'id_ed25519.pub',
        'id_ecdsa',
        'id_dsa',
        'known_hosts',
        'authorized_keys',
        
        # Package manager auth
        '.npmrc',
        '.pypirc',
        '.yarnrc',
        '.docker/config.json',
        
        # Cloud credentials
        '.aws/credentials',
        '.aws/config',
        'gcloud/credentials.db',
        '.azure/credentials',
        
        # Git credentials
        '.git-credentials',
        '.gitconfig',  # Can contain credentials
        '.git/config', # Can contain tokens
        
        # Database
        '.pgpass',
        '.my.cnf',
        '.mongorc.js',
    }
    
    # File extensions to block
    SENSITIVE_EXTENSIONS = {
        '.pem',      # Certificates/keys
        '.key',      # Private keys
        '.p12',      # PKCS#12 certificates
        '.pfx',      # Windows certificates
        '.jks',      # Java keystore
        '.keystore', # Generic keystore
        '.crt',      # Certificates (sometimes contain keys)
        '.cer',      # Certificates
    }
    
    # Patterns to match anywhere in path
    SENSITIVE_PATH_PATTERNS = [
        'secret',
        'credential',
        'private_key',
        'privatekey',
        '.env.',     # Catches .env.anything
        '/secrets/', # Secrets directories
    ]
    
    # =============================================================================
    # HOOK LOGIC
    # =============================================================================
    
    def is_sensitive_file(file_path: str) -> tuple[bool, str]:
        """
        Check if a file path matches sensitive patterns.
        Returns (is_sensitive, reason).
        """
        if not file_path:
            return False, ""
        
        path = Path(file_path)
        file_name = path.name
        file_lower = file_path.lower()
        
        # Check exact filename match
        if file_name in SENSITIVE_FILENAMES:
            return True, f"'{file_name}' is a known sensitive file"
        
        # Check extension
        if path.suffix.lower() in SENSITIVE_EXTENSIONS:
            return True, f"'{path.suffix}' files may contain private keys or certificates"
        
        # Check path patterns
        for pattern in SENSITIVE_PATH_PATTERNS:
            if pattern in file_lower:
                return True, f"path contains sensitive pattern '{pattern}'"
        
        return False, ""
    
    
    def extract_file_path(data: dict) -> str:
        """
        Extract file path from tool input.
        Different tools use different parameter names.
        """
        tool_input = data.get('tool_input', {})
        
        # Try common parameter names
        for key in ['file_path', 'path', 'filename', 'file']:
            if key in tool_input:
                return tool_input[key]
        
        # For Bash tool, check the command for file references
        command = tool_input.get('command', '')
        if command:
            # This is a simplified check - you might want more sophisticated parsing
            for pattern in SENSITIVE_FILENAMES:
                if pattern in command:
                    return pattern
            for ext in SENSITIVE_EXTENSIONS:
                if ext in command:
                    return command  # Return command as "file" so it gets blocked
        
        return ""
    
    
    def main():
        try:
            # Read JSON input from stdin
            data = json.load(sys.stdin)
            
            # Get tool name for better error messages
            tool_name = data.get('tool_name', 'unknown')
            
            # Extract file path
            file_path = extract_file_path(data)
            
            if not file_path:
                # No file path found, allow the operation
                sys.exit(0)
            
            # Check if sensitive
            is_sensitive, reason = is_sensitive_file(file_path)
            
            if is_sensitive:
                # Construct error message that will be fed back to Claude
                error_msg = f"""
    โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
    โ•‘                    ๐Ÿ”’ SECURITY HOOK BLOCKED                       โ•‘
    โ• โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•ฃ
    โ•‘ Tool: {tool_name}
    โ•‘ File: {file_path}
    โ•‘ 
    โ•‘ Reason: {reason}
    โ•‘
    โ•‘ This file likely contains secrets, credentials, or private keys
    โ•‘ that should not be accessed programmatically.
    โ•‘
    โ•‘ Recommended actions:
    โ•‘ โ€ข Use environment variables instead of reading .env directly
    โ•‘ โ€ข Ask the user for specific (non-sensitive) information
    โ•‘ โ€ข Reference .env.example for variable names only
    โ•‘ โ€ข Store secrets in a proper secrets manager
    โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
    """.strip()
                
                # Print to stderr (will be fed back to Claude)
                print(error_msg, file=sys.s
  • hooks/end-of-turn.shGitHub
    Read the script
    #!/usr/bin/env bash
    # =============================================================================
    # End-of-Turn Quality Gate Hook
    # =============================================================================
    #
    # This hook runs when Claude finishes responding (Stop event).
    # It performs quality checks to catch issues before they accumulate.
    #
    # Usage:
    #   Add to ~/.claude/settings.json or .claude/settings.json:
    #   {
    #     "hooks": {
    #       "Stop": [
    #         {
    #           "matcher": "*",
    #           "hooks": [
    #             {
    #               "type": "command",
    #               "command": "~/.claude/hooks/end-of-turn.sh"
    #             }
    #           ]
    #         }
    #       ]
    #     }
    #   }
    #
    # Exit codes:
    #   0 = Success (continue normally)
    #   1 = Error shown to user
    #   2 = Block and feed stderr to Claude (use sparingly for Stop hooks)
    #
    # =============================================================================
    
    set -euo pipefail
    
    # -----------------------------------------------------------------------------
    # Configuration
    # -----------------------------------------------------------------------------
    
    # Set to "true" to enable verbose logging
    VERBOSE="${CLAUDE_HOOK_VERBOSE:-false}"
    
    # Maximum time for checks (seconds)
    TIMEOUT=30
    
    # -----------------------------------------------------------------------------
    # Helper Functions
    # -----------------------------------------------------------------------------
    
    log() {
        if [[ "$VERBOSE" == "true" ]]; then
            echo "[end-of-turn] $*" >&2
        fi
    }
    
    run_check() {
        local name="$1"
        local cmd="$2"
        
        log "Running: $name"
        
        if timeout "$TIMEOUT" bash -c "$cmd" 2>/dev/null; then
            log "โœ“ $name passed"
            return 0
        else
            log "โœ— $name failed (non-blocking)"
            return 0  # Don't fail the hook, just log
        fi
    }
    
    # -----------------------------------------------------------------------------
    # Detect Project Type
    # -----------------------------------------------------------------------------
    
    is_nodejs() {
        [[ -f "package.json" ]]
    }
    
    is_typescript() {
        [[ -f "tsconfig.json" ]]
    }
    
    is_python() {
        [[ -f "pyproject.toml" ]] || [[ -f "setup.py" ]] || [[ -f "requirements.txt" ]]
    }
    
    is_rust() {
        [[ -f "Cargo.toml" ]]
    }
    
    is_go() {
        [[ -f "go.mod" ]]
    }
    
    # -----------------------------------------------------------------------------
    # Project-Specific Checks
    # -----------------------------------------------------------------------------
    
    check_nodejs() {
        log "Detected Node.js project"
        
        # Check if node_modules exists
        if [[ ! -d "node_modules" ]]; then
            log "node_modules missing, skipping npm checks"
            return 0
        fi
        
        # Run lint if available
        if grep -q '"lint"' package.json 2>/dev/null; then
            run_check "npm lint" "npm run lint --silent"
        fi
        
        # Run typecheck if TypeScript
        if is_typescript; then
            if grep -q '"typecheck"' package.json 2>/dev/null; then
                run_check "typecheck" "npm run typecheck --silent"
            elif command -v tsc &>/dev/null; then
                run_check "tsc" "tsc --noEmit"
            fi
        fi
    }
    
    check_python() {
        log "Detected Python project"
        
        # Ruff (fast Python linter)
        if command -v ruff &>/dev/null; then
            run_check "ruff" "ruff check . --fix --silent"
        fi
        
        # Black (formatter)
        if command -v black &>/dev/null; then
            run_check "black" "black --check --quiet ."
        fi
        
        # MyPy (type checker)
        if command -v mypy &>/dev/null && [[ -f "mypy.ini" || -f "pyproject.toml" ]]; then
            run_check "mypy" "mypy . --silent-imports"
        fi
    }
    
    check_rust() {
        log "Detected Rust project"
        
        # Cargo check (fast type checking)
        if command -v cargo &>/dev/null; then
            run_check "cargo check" "cargo check --quiet"
        fi
        
        # Clippy (linter)
        if command -v cargo &>/dev/null; then
            run_check "clippy" "cargo clippy --quiet -- -D warnings"
        fi
    }
    
    check_go() {
        log "Detected Go project"
        
        # Go vet
        if command -v go &>/dev/null; then
            run_check "go vet" "go vet ./..."
        fi
        
        # Staticcheck
        if command -v staticcheck &>/dev/null; then
            run_check "staticcheck" "staticcheck ./..."
        fi
    }
    
    # -----------------------------------------------------------------------------
    # Universal Checks
    # -----------------------------------------------------------------------------
    
    check_secrets() {
        log "Checking for exposed secrets"
        
        # Simple grep for common secret patterns in staged files
        if git rev-parse --git-dir &>/dev/null; then
            local staged_files
            staged_files=$(git diff --cached --name-only 2>/dev/null || true)
            
            if [[ -n "$staged_files" ]]; then
                # Check for hardcoded secrets (simplified pattern)
                if echo "$staged_files" | xargs grep -l -E "(API_KEY|SECRET|TOKEN|PASSWORD)\s*[=:]\s*['\"][A-Za-z0-9_\-]{16,}" 2>/dev/null; then
                    echo "โš ๏ธ  Warning: Possible hardcoded secrets in staged files" >&2
                fi
            fi
        fi
    }
    
    check_env_committed() {
        log "Checking .env not staged"
        
        if git rev-parse --git-dir &>/dev/null; then
            if git diff --cached --name-only 2>/dev/null | grep -q "^\.env"; then
                echo "โš ๏ธ  Warning: .env file is staged for commit!" >&2
            fi
        fi
    }
    
    # -----------------------------------------------------------------------------
    # Main
    # -----------------------------------------------------------------------------
    
    main() {
        log "Starting end-of-turn checks"
        
        # Run project-specific checks
        if is_nodejs; then
            check_nodejs
        fi
        
        if is_python; then
            check_python
        fi
        
        if is_rust; then
            check_rust
        fi
        
        if is_go; then
            check_go
        fi
        
        # Universal checks
        check_secrets
        check_env_committed
        
        log "End-of-turn checks complete"
        exit 0
    }
    
    main "$@"
    
  • hooks/notify.shGitHub
    Read the script
    #!/usr/bin/env bash
    # =============================================================================
    # Notification Hook: Desktop Alerts
    # =============================================================================
    #
    # This hook runs when Claude Code sends notifications.
    # It triggers desktop notifications so you know when Claude needs input.
    #
    # Works on:
    #   - macOS (osascript)
    #   - Linux (notify-send)
    #   - Windows WSL (powershell)
    #
    # Usage:
    #   Add to ~/.claude/settings.json:
    #   {
    #     "hooks": {
    #       "Notification": [
    #         {
    #           "matcher": "*",
    #           "hooks": [
    #             {
    #               "type": "command",
    #               "command": "~/.claude/hooks/notify.sh"
    #             }
    #           ]
    #         }
    #       ]
    #     }
    #   }
    # =============================================================================
    
    set -euo pipefail
    
    # Read JSON input from stdin
    INPUT=$(cat)
    
    # Extract notification content
    CONTENT=$(echo "$INPUT" | jq -r '.content // "Claude needs your attention"')
    
    # Truncate long messages
    if [[ ${#CONTENT} -gt 100 ]]; then
        CONTENT="${CONTENT:0:100}..."
    fi
    
    # -----------------------------------------------------------------------------
    # Send notification based on OS
    # -----------------------------------------------------------------------------
    
    send_notification() {
        local title="Claude Code"
        local message="$1"
        
        # macOS
        if [[ "$OSTYPE" == "darwin"* ]]; then
            osascript -e "display notification \"$message\" with title \"$title\" sound name \"Glass\"" 2>/dev/null || true
            return
        fi
        
        # Linux with notify-send
        if command -v notify-send &>/dev/null; then
            notify-send "$title" "$message" -u normal -t 5000 2>/dev/null || true
            return
        fi
        
        # Windows WSL
        if grep -qi microsoft /proc/version 2>/dev/null; then
            powershell.exe -Command "
                [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
                [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
                \$template = '<toast><visual><binding template=\"ToastText02\"><text id=\"1\">$title</text><text id=\"2\">$message</text></binding></visual></toast>'
                \$xml = New-Object Windows.Data.Xml.Dom.XmlDocument
                \$xml.LoadXml(\$template)
                \$toast = [Windows.UI.Notifications.ToastNotification]::new(\$xml)
                [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier('Claude Code').Show(\$toast)
            " 2>/dev/null || true
            return
        fi
        
        # Fallback: terminal bell
        echo -e '\a'
    }
    
    send_notification "$CONTENT"
    exit 0
    

Read the script before you install anything that runs on your machine. This is the one part of a plugin that acts without being asked.

@thedecipherist
Ships withclaude-code-mastery

The complete guide to maximizing Claude Code: Global CLAUDE.md, MCP Servers, Commands, Hooks, Skills, and Why Single-Purpose Chats Matter. This version is obsolete by now.

Stars on GitHub

Momentum

stars in total
558
Star history of TheDecipherist/claude-code-mastery on GitHub, a chart by star-history.com

More plugins that ship hooks.

claudeforge

claudeforge

Automatically creates, enhances and maintains CLAUDE.md files for Claude Code projects, so you don't have to write and update them by hand.

3 hooks+1434
@alirezarezvani@alirezarezvani
Install Plugin
scaccogatto-okf

scaccogatto-okf

Gives your coding agent skills to author, maintain, validate and visualize Open Knowledge Format bundles, portable markdown knowledge that both your team and your agents can read. Includes a backfill skill for building a bundle from an existing repository's git history and session transcripts.

4 skills+3430
@scaccogatto@scaccogatto
Install Plugin
reviewable-html-workbench

reviewable-html-workbeโ€ฆ

Turns design docs and plan drafts into HTML pages you can comment on inline. Fires when you ask to review a design, preview a plan, or render visual output.

3 skills1 hook302
@u-ichi@u-ichi
Install Plugin
filetree

filetree

A Claude Code plugin that maintains FILETREE.md, a one-line description per file with content hashes for staleness detection. Lets the LLM grasp repo layout in a few hundred tokens before touching code.

1 skill+2164
@nekocode@nekocode
Install Plugin
fluencyloop

fluencyloop

Keeps you fluent in code that AI writes: each feature is designed, built with the reasoning behind each decision explained, and recorded as docs, decisions and review summaries, so the understanding stays with the code.

6 skills1 hook47
@baokhang83@baokhang83
Install Plugin
d2

d2

A Claude Code plugin that reads your codebase and draws its infrastructure and architecture with D2, then keeps those diagrams in step with the code as it changes. Command: /d2:diagram.

1 skill+218
@heathdutton@heathdutton
Install Plugin
trigger-tree

trigger-tree

Shows which docs your AI agent actually discovers, using local telemetry with no token cost. Includes a CI gate that fails a pull request with the affected file and a suggested fix.

1 skill4 hooks16
@hedde@hedde
Install Plugin

Questions about the hooks in claude-code-mastery.

Which coding agents can use the hooks in claude-code-mastery?
The hooks in claude-code-mastery install in Claude Code and Cursor: each runs Claude Code hooks from .claude/settings.json, so copy the hooks there.