Skip to content

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

18 Commits

Folders and files

Repository files navigation

command-guard

Configurable guardrails for Claude Code and Codex CLI - block commands, protect files, enforce workflows.

Overview

command-guard is a plugin for both Claude Code and Codex CLI. It provides configurable guardrails for blocking or warning about tool usage and ships with no default rules — all configuration comes from your project's .claude/command-guard.json (the same file is read under both runtimes). The override mechanism, safe patterns, and warning throttle all work identically.

Installation

Claude Code

claude plugin marketplace add golergka/command-guard
claude plugin install command-guard@golergka-command-guard

For local development/testing:

claude --plugin-dir /path/to/command-guard

Codex CLI

codex plugin marketplace add golergka/command-guard
codex plugin add command-guard@golergka-command-guard

Codex auto-discovers hooks.json at the plugin root, so the same guard fires for *exec_command tool calls. The plugin reads either CLAUDE_PROJECT_DIR or CODEX_PROJECT_DIR to find .claude/command-guard.json, so config lives in the same place either way.

Plugins

This repository contains multiple independent plugins. Install only what you need:

Plugin Description Install command
command-guard Configurable rules to block or warn about tool usage claude plugin install command-guard@golergka-command-guard
commit-guard Prevents Claude from finishing with uncommitted changes claude plugin install commit-guard@golergka-command-guard

command-guard

Configuration

Create .claude/command-guard.json in your project root:

{
  "rules": [
    {
      "match": "command",
      "pattern": "git\\s+reset\\s+--hard",
      "message": "git reset --hard destroys uncommitted changes. Use git stash first.",
      "severity": "error"
    },
    {
      "match": "file_path",
      "pattern": "patches/.*\\.patch$",
      "message": "Patch files should not be edited directly. Use pnpm patch workflow.",
      "severity": "error"
    },
    {
      "match": "tool_name",
      "pattern": "mcp__betterstack__",
      "message": "Consider using better-stack-logs agent for context isolation.",
      "severity": "warning"
    }
  ],
  "safePatterns": ["git\\s+checkout\\s+-b\\s"]
}

If no config file exists, all tool uses are allowed (empty rules = no blocking).

Rule Schema

Field Required Type Description
match Yes "command" | "file_path" | "tool_name" What to match against
pattern Yes string (regex) Pattern to match
message Yes string Message shown when triggered
severity Yes "error" | "warning" error=block, warning=reminder
case_sensitive No boolean Default: false

Match Types

command

Matches against Bash command content. Commands are:

  • Split on chain operators (&&, ||, ;, |)
  • Normalized (absolute paths like /usr/bin/git become git)
  • Stripped of quoted strings to avoid false positives

file_path

Matches against file paths in Edit and Write tool calls.

tool_name

Matches against the tool name. Useful for MCP tools like mcp__betterstack__telemetry_query.

Severity Levels

error

Blocks the tool use entirely. The user sees a block message and the tool doesn't execute.

BLOCKED: git reset --hard destroys all uncommitted changes permanently. Use 'git stash' first.

Context: git reset --hard HEAD~1

To override, add a comment: # OVERRIDE: <reason>

warning

Shows a reminder after the tool completes (PostToolUse). Doesn't block execution.

Warnings are throttled per (working directory, Claude session, rule) — by default, each rule surfaces on hit #1, #11, #21, … for a given session and folder. Intermediate hits are silently suppressed so a noisy rule doesn't flood the conversation. Errors are never throttled.

Override the interval with the top-level warningThrottle field in .claude/command-guard.json (default 10, set to 1 to disable throttling):

{
  "warningThrottle": 10,
  "rules": [ ... ]
}

Counter state lives in ~/.claude/command-guard/throttle/<session_id>.json and is pruned automatically once the directory grows past ~50 sessions.

Safe Patterns

The safePatterns array contains regex patterns that bypass blocking rules. This is useful for allowing safe variants of otherwise dangerous commands:

{
  "safePatterns": [
    "git\\s+checkout\\s+-b\\s",
    "git\\s+restore\\s+--staged",
    "git\\s+push\\s+--force-with-lease"
  ]
}

Override Mechanism

Any blocked command can be overridden by adding a comment with explicit reasoning:

git reset --hard  # OVERRIDE: cleaning up failed rebase state

The reason must be at least 5 characters. Override usage is logged to stderr.

Examples

Block Destructive Git Commands

{
  "rules": [
    {
      "match": "command",
      "pattern": "git\\s+reset\\s+--hard",
      "message": "git reset --hard destroys all uncommitted changes. Use 'git stash' first.",
      "severity": "error"
    },
    {
      "match": "command",
      "pattern": "git\\s+push\\s+(\\S+\\s+)*(-f|--force)(?!-with-lease)",
      "message": "git push --force overwrites remote history. Use --force-with-lease for safer force push.",
      "severity": "error"
    }
  ],
  "safePatterns": ["git\\s+push\\s+--force-with-lease"]
}

Enforce Workflow Skills

{
  "rules": [
    {
      "match": "command",
      "pattern": "^prettier\\s+(?!--help)",
      "message": "Use /automated-checks skill for formatting, linting, and type checking.",
      "severity": "error"
    },
    {
      "match": "command",
      "pattern": "git\\s+commit\\s+",
      "message": "Make sure you have used /git-commits skill for proper conventional commits.",
      "severity": "warning"
    }
  ]
}

Protect Generated Files

{
  "rules": [
    {
      "match": "file_path",
      "pattern": "(^|/)patches/.*\\.patch$",
      "message": "Patch files are generated by pnpm. Use pnpm patch workflow instead.",
      "severity": "error"
    },
    {
      "match": "file_path",
      "pattern": "supabase/migrations/",
      "message": "Migration files should be generated, not written directly.",
      "severity": "warning"
    }
  ]
}

MCP Tool Reminders

{
  "rules": [
    {
      "match": "tool_name",
      "pattern": "mcp__betterstack__",
      "message": "Consider using better-stack-logs agent for context isolation.",
      "severity": "warning"
    }
  ]
}

Skill

The plugin includes a /command-guard skill for viewing and editing configuration. Use it to:

  1. View current configuration
  2. Add new rules
  3. Edit existing rules
  4. Add safe patterns

How It Works

The plugin registers hooks for:

  • PreToolUse (Bash, Edit, Write, MCP tools): Checks for error severity rules and blocks if matched
  • PostToolUse (all tools): Checks for warning severity rules and shows reminders

commit-guard

Prevents Claude from finishing a session with uncommitted changes. Uses a Stop hook — when Claude tries to end the conversation, the hook checks git status and blocks if there are uncommitted changes.

Behavior

  • If the working tree is dirty, Claude is re-prompted to commit before finishing
  • Claude can acknowledge the situation by including UNCOMMITTED_OK in its message (e.g. when it only did research or the user told it not to commit)
  • Does nothing outside of git repositories

Development

Setup

The repository includes .claude/settings.json which installs both plugins from the local directory for development:

{
  "plugins": ["./", "./plugins/commit-guard/"]
}

Running Tests

Tests use pytest and can be run without any Claude Code or LLM calls:

pytest tests/ -v

The tests cover:

  • Unit tests for individual functions (rule matching, command parsing, etc.)
  • Integration tests that run the script as a subprocess with sample configs

Test Fixtures

Test fixtures are in tests/fixtures/. The basic_rules.json file contains sample rules for testing.

About

No description, website, or topics provided.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages