Skip to content

πŸ˜‡ Gentleman Guardian Angel (gga) - Provider-agnostic code review using AI. Use Claude, Gemini, Codex, Ollama to enforce your coding standards.

License

Notifications You must be signed in to change notification settings

Gentleman-Programming/gentleman-guardian-angel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

59 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

image

Provider-agnostic code review using AI
Use Claude, Gemini, Codex, OpenCode, Ollama, LM Studio, GitHub Models, or any AI to enforce your coding standards.
Zero dependencies. Pure Bash. Works everywhere.

Version License Bash Homebrew Tests PRs Welcome

Installation β€’ Quick Start β€’ Providers β€’ Commands β€’ Configuration β€’ Caching β€’ Development


Example

image

🎯 Why?

You have coding standards. Your team ignores them. Code reviews catch issues too late.

Gentleman Guardian Angel runs on every commit, validating your staged files against your project's AGENTS.md (or any rules file). It's like having a senior developer review every line before it hits the repo.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   git commit    β”‚ ──▢ β”‚  AI Review   β”‚ ──▢ β”‚  βœ… Pass/Fail   β”‚
β”‚  (staged files) β”‚     β”‚  (any LLM)   β”‚     β”‚  (with details) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key features:

  • πŸ”Œ Provider agnostic - Use whatever AI you have installed
  • πŸ“¦ Zero dependencies - Pure Bash, no Node/Python/Go required
  • πŸͺ Git native - Installs as a standard pre-commit hook
  • βš™οΈ Highly configurable - File patterns, exclusions, custom rules
  • 🚨 Strict mode - Fail CI on ambiguous responses
  • ⚑ Smart caching - Skip unchanged files for faster reviews
  • ⏱️ Timeout & progress - Configurable timeout with visual spinner
  • πŸ” PR review mode - Review full PRs, not just last commit
  • 🍺 Homebrew ready - One command install

πŸ“¦ Installation

Homebrew (Recommended) 🍺

brew tap gentleman-programming/tap
brew install gga

Or in a single command:

brew install gentleman-programming/tap/gga

Manual Installation

git clone https://github.com/Gentleman-Programming/gentleman-guardian-angel.git
cd gga
./install.sh

Verify Installation

gga version
# Output: gga v2.7.0

πŸš€ Quick Start

# 1. Go to your project
cd ~/your-project

# 2. Initialize config
gga init

# 3. Create your rules file
touch AGENTS.md  # Add your coding standards

# 4. Install the git hook
gga install

# 5. Done! Now every commit gets reviewed πŸŽ‰

🎬 Real World Example

Let's walk through a complete example from setup to commit:

Step 1: Setup in your project

$ cd ~/projects/my-react-app

$ gga init

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Gentleman Guardian Angel v2.2.0
  Provider-agnostic code review using AI
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

βœ… Created config file: .gga

ℹ️  Next steps:
  1. Edit .gga to set your preferred provider
  2. Create AGENTS.md with your coding standards
  3. Run: gga install

Step 2: Configure your provider

$ cat .gga

# AI Provider (required)
PROVIDER="claude"

# File patterns to include in review (comma-separated)
FILE_PATTERNS="*.ts,*.tsx,*.js,*.jsx"

# File patterns to exclude from review (comma-separated)
EXCLUDE_PATTERNS="*.test.ts,*.spec.ts,*.test.tsx,*.spec.tsx,*.d.ts"

# File containing code review rules
RULES_FILE="AGENTS.md"

# Strict mode: fail if AI response is ambiguous
STRICT_MODE="true"

Step 3: Create your coding standards

$ cat > AGENTS.md << 'EOF'
# Code Review Rules

## TypeScript
- No `any` types - use proper typing
- Use `const` over `let` when possible
- Prefer interfaces over type aliases for objects

## React
- Use functional components with hooks
- No `import * as React` - use named imports like `import { useState }`
- All images must have alt text for accessibility

## Styling
- Use Tailwind CSS utilities only
- No inline styles or CSS-in-JS
- No hardcoded colors - use design system tokens
EOF

Step 4: Install the git hook

$ gga install

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Gentleman Guardian Angel v2.2.0
  Provider-agnostic code review using AI
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

βœ… Installed pre-commit hook: /Users/dev/projects/my-react-app/.git/hooks/pre-commit

Step 5: Make some changes and commit

$ git add src/components/Button.tsx
$ git commit -m "feat: add new button component"

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Gentleman Guardian Angel v2.2.0
  Provider-agnostic code review using AI
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ️  Provider: claude
ℹ️  Rules file: AGENTS.md
ℹ️  File patterns: *.ts,*.tsx,*.js,*.jsx
ℹ️  Cache: enabled

Files to review:
  - src/components/Button.tsx

ℹ️  Sending to claude for review...

STATUS: FAILED

Violations found:

1. **src/components/Button.tsx:3** - TypeScript Rule
   - Issue: Using `any` type for props
   - Fix: Define proper interface for ButtonProps

2. **src/components/Button.tsx:15** - React Rule
   - Issue: Using `import * as React`
   - Fix: Use `import { useState, useCallback } from 'react'`

3. **src/components/Button.tsx:22** - Styling Rule
   - Issue: Hardcoded color `#3b82f6`
   - Fix: Use Tailwind class `bg-blue-500` instead

❌ CODE REVIEW FAILED

Fix the violations listed above before committing.

Step 6: Fix issues and commit again

$ git add src/components/Button.tsx
$ git commit -m "feat: add new button component"

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  Gentleman Guardian Angel v2.2.0
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ℹ️  Provider: claude
ℹ️  Cache: enabled

Files to review:
  - src/components/Button.tsx

ℹ️  Sending to claude for review...

STATUS: PASSED

All files comply with the coding standards defined in AGENTS.md.

βœ… CODE REVIEW PASSED

[main 4a2b3c1] feat: add new button component
 1 file changed, 45 insertions(+)
 create mode 100644 src/components/Button.tsx

πŸ“‹ Commands

Command Description Example
init Create sample .gga config file gga init
install Install git pre-commit hook (default) gga install
install --commit-msg Install git commit-msg hook (for commit message validation) gga install --commit-msg
uninstall Remove git hooks from current repo gga uninstall
run Run code review on staged files gga run
run --ci Run code review on last commit (for CI/CD) gga run --ci
run --pr-mode Review all files changed in the full PR gga run --pr-mode
run --pr-mode --diff-only PR review with diffs only (faster, cheaper) gga run --pr-mode --diff-only
run --no-cache Run review ignoring cache gga run --no-cache
config Display current configuration and status gga config
cache status Show cache status for current project gga cache status
cache clear Clear cache for current project gga cache clear
cache clear-all Clear all cached data gga cache clear-all
help Show help message with all commands gga help
version Show installed version gga version

Command Details

gga init

Creates a sample .gga configuration file in your project root with sensible defaults.

$ gga init
βœ… Created config file: .gga

gga install

Installs a git hook that automatically runs code review on every commit.

Default (pre-commit hook):

$ gga install
βœ… Installed pre-commit hook: .git/hooks/pre-commit

With commit message validation (commit-msg hook):

$ gga install --commit-msg
βœ… Installed commit-msg hook: .git/hooks/commit-msg

The --commit-msg flag installs a commit-msg hook instead of pre-commit. This allows GGA to also validate your commit message (e.g., conventional commits format, issue references, etc.). The commit message is automatically included in the AI review.

If a hook already exists, GGA will append to it rather than replacing it.

gga uninstall

Removes the git pre-commit hook from your repository.

$ gga uninstall
βœ… Removed pre-commit hook

gga run [--no-cache]

Runs code review on currently staged files. Uses intelligent caching by default to skip unchanged files.

$ git add src/components/Button.tsx
$ gga run
# Reviews the staged file (uses cache)

$ gga run --no-cache
# Forces review of all files, ignoring cache

gga config

Shows the current configuration, including where config files are loaded from and all settings.

$ gga config

Current Configuration:

Config Files:
  Global:  Not found
  Project: .gga

Values:
  PROVIDER:          claude
  FILE_PATTERNS:     *.ts,*.tsx,*.js,*.jsx
  EXCLUDE_PATTERNS:  *.test.ts,*.spec.ts
  RULES_FILE:        AGENTS.md
  STRICT_MODE:       true
  TIMEOUT:           300s
  PR_BASE_BRANCH:    auto-detect

Rules File: Found

⚑ Smart Caching

GGA includes intelligent caching to speed up reviews by skipping files that haven't changed.

How It Works

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        Cache Logic                               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  1. Hash AGENTS.md + .gga config                                β”‚
β”‚     └─► If changed β†’ Invalidate ALL cache                       β”‚
β”‚                                                                  β”‚
β”‚  2. For each staged file:                                        β”‚
β”‚     └─► Hash file content                                        β”‚
β”‚         └─► If hash exists in cache with PASSED β†’ Skip          β”‚
β”‚         └─► If not cached β†’ Send to AI for review               β”‚
β”‚                                                                  β”‚
β”‚  3. After PASSED review:                                         β”‚
β”‚     └─► Store file hash in cache                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Cache Invalidation

The cache automatically invalidates when:

Change Effect
File content changes Only that file is re-reviewed
AGENTS.md changes All files are re-reviewed
.gga config changes All files are re-reviewed

Cache Commands

# Check cache status
$ gga cache status

Cache Status:

  Cache directory: ~/.cache/gga/a1b2c3d4...
  Cache validity: Valid
  Cached files: 12
  Cache size: 4.0K

# Clear project cache
$ gga cache clear
βœ… Cleared cache for current project

# Clear all cache (all projects)
$ gga cache clear-all
βœ… Cleared all cache data

Bypass Cache

# Force review all files, ignoring cache
gga run --no-cache

Cache Location

~/.cache/gga/
β”œβ”€β”€ <project-hash-1>/
β”‚   β”œβ”€β”€ metadata          # Hash of AGENTS.md + .gga
β”‚   └── files/
β”‚       β”œβ”€β”€ <file-hash-a> # "PASSED"
β”‚       └── <file-hash-b> # "PASSED"
└── <project-hash-2>/
    └── ...

πŸ”Œ Providers

Use whichever AI CLI you have installed:

Provider Config Value CLI Command Used Installation
Claude claude echo "prompt" | claude --print claude.ai/code
Gemini gemini echo "prompt" | gemini github.com/google-gemini/gemini-cli
Codex codex codex exec "prompt" npm i -g @openai/codex
OpenCode opencode echo "prompt" | opencode run opencode.ai
Ollama ollama:<model> ollama run <model> "prompt" ollama.ai
LM Studio lmstudio[:model] HTTP API call to local server lmstudio.ai
GitHub Models github:<model> HTTP API via gh auth token github.com/marketplace/models

Provider Examples

# Use Claude (recommended - most reliable)
PROVIDER="claude"

# Use Google Gemini
PROVIDER="gemini"

# Use OpenAI Codex
PROVIDER="codex"

# Use OpenCode (uses default model)
PROVIDER="opencode"

# Use OpenCode with specific model
PROVIDER="opencode:anthropic/claude-opus-4-5"

# Use Ollama with Llama 3.2
PROVIDER="ollama:llama3.2"

# Use Ollama with CodeLlama (optimized for code)
PROVIDER="ollama:codellama"

# Use Ollama with Qwen Coder
PROVIDER="ollama:qwen2.5-coder"

# Use Ollama with DeepSeek Coder
PROVIDER="ollama:deepseek-coder"

# Use LM Studio with default model
PROVIDER="lmstudio"

# Use LM Studio with specific model
PROVIDER="lmstudio:llama-3.2-3b-instruct"

# Use LM Studio with custom host
LMSTUDIO_HOST="http://localhost:8080/v1"
PROVIDER="lmstudio"

# Use GitHub Models (requires: gh auth login)
PROVIDER="github:gpt-4o"
PROVIDER="github:gpt-4.1"
PROVIDER="github:deepseek-r1"
PROVIDER="github:grok-3"

βš™οΈ Configuration

Config File: .gga

Create this file in your project root:

# AI Provider (required)
# Options: claude, gemini, codex, opencode, ollama:<model>, lmstudio[:model], github:<model>
PROVIDER="claude"

# File patterns to review (comma-separated globs)
# Default: * (all files)
FILE_PATTERNS="*.ts,*.tsx,*.js,*.jsx"

# Patterns to exclude from review (comma-separated globs)
# Default: none
EXCLUDE_PATTERNS="*.test.ts,*.spec.ts,*.d.ts"

# File containing your coding standards
# Default: AGENTS.md
RULES_FILE="AGENTS.md"

# Fail if AI response is ambiguous (recommended for CI)
# Default: true
STRICT_MODE="true"

# Timeout in seconds for AI provider response
# Default: 300 (5 minutes)
TIMEOUT="300"

# Base branch for --pr-mode (auto-detects main/master/develop if empty)
# PR_BASE_BRANCH="main"

Configuration Options

Option Required Default Description
PROVIDER βœ… Yes - AI provider to use
FILE_PATTERNS No * Comma-separated file patterns to include
EXCLUDE_PATTERNS No - Comma-separated file patterns to exclude
RULES_FILE No AGENTS.md Path to your coding standards file
STRICT_MODE No true Fail on ambiguous AI responses
TIMEOUT No 300 Max seconds to wait for AI response
PR_BASE_BRANCH No auto-detect Base branch for --pr-mode

Config Hierarchy (Priority Order)

  1. Environment variable GGA_PROVIDER, GGA_TIMEOUT (highest priority)
  2. Project config .gga (in project root)
  3. Global config ~/.config/gga/config (lowest priority)
# Override provider for a single run
GGA_PROVIDER="gemini" gga run

# Or export for the session
export GGA_PROVIDER="ollama:llama3.2"

# Override timeout for a single run
GGA_TIMEOUT=600 gga run

πŸ“ Rules File (AGENTS.md)

The AI needs to know your standards. Create an AGENTS.md file.

Best Practices for AGENTS.md

Your rules file should be optimized for LLM parsing, not for human documentation. Here's why and how:

1. Keep it Concise (~100-200 lines)

Large files dilute the AI's focus. A focused, concise file produces better reviews.

# ❌ Bad: Verbose explanations

## TypeScript Guidelines

When writing TypeScript code, it's important to consider type safety.
The `any` type should be avoided because it defeats the purpose of
using TypeScript in the first place. Instead, you should always...
(continues for 50 more lines)

# βœ… Good: Direct and actionable

## TypeScript

REJECT if:

- `any` type used
- Missing return types on public functions
- Type assertions without justification

2. Use Clear Action Keywords

Use REJECT, REQUIRE, PREFER to give the AI clear signals:

Keyword Meaning AI Action
REJECT if Hard rule, must fail Returns STATUS: FAILED
REQUIRE Mandatory pattern Returns STATUS: FAILED if missing
PREFER Soft recommendation May note but won't fail

3. Use References for Complex Projects

For large projects or monorepos, use references instead of concatenating multiple files:

# Code Review Rules

## References

- UI guidelines: `ui/AGENTS.md`
- API guidelines: `api/AGENTS.md`
- Shared rules: `docs/CODE-STYLE.md`

---

## Critical Rules (ALL files)

REJECT if:

- Hardcoded secrets/credentials
- `console.log` in production code
- Missing error handling

Why references work: Claude, Gemini, and Codex have built-in tools to read files. When they see a reference like "ui/AGENTS.md", they can go read it if they need more context. This keeps your main file focused while allowing deep dives when needed.

⚠️ Note for Ollama users: Ollama is a pure LLM without file-reading tools. If you use Ollama and need multiple rules files, you'll need to manually consolidate them into one file.

4. Structure for Scanning

Use bullet points, not paragraphs. The AI scans faster:

# βœ… Good: Scannable structure

## TypeScript/React

REJECT if:

- `import * as React` β†’ use `import { useState }`
- Union types `type X = "a" | "b"` β†’ use `const X = {...} as const`
- `any` type without `// @ts-expect-error` justification

PREFER:

- Named exports over default exports
- Composition over inheritance

5. Real-World Example

Here's a battle-tested example from a production monorepo:

# Code Review Rules

## References

- UI details: `ui/AGENTS.md`
- SDK details: `sdk/AGENTS.md`

---

## ALL FILES

REJECT if:

- Hardcoded secrets/credentials
- `any` type (TypeScript) or missing type hints (Python)
- Code duplication (violates DRY)
- Silent error handling (empty catch blocks)

---

## TypeScript/React

REJECT if:

- `import React` β†’ use `import { useState }`
- `var()` or hex colors in className β†’ use Tailwind
- `useMemo`/`useCallback` without justification (React 19 Compiler handles this)
- Missing `"use client"` in client components

PREFER:

- `cn()` for conditional class merging
- Semantic HTML over divs
- Colocated files (component + test + styles)

---

## Python

REJECT if:

- Missing type hints on public functions
- Bare `except:` without specific exception
- `print()` instead of `logger`

REQUIRE:

- Docstrings on all public classes/methods

---

## Response Format

FIRST LINE must be exactly:
STATUS: PASSED
or
STATUS: FAILED

If FAILED, list: `file:line - rule violated - issue`

This file is 89 lines, uses clear keywords, and has references for component-specific rules.

πŸ’‘ Pro tip: Your AGENTS.md can also serve as documentation for human reviewers!


🎨 Project Examples

TypeScript/React Project

# .gga
PROVIDER="claude"
FILE_PATTERNS="*.ts,*.tsx"
EXCLUDE_PATTERNS="*.test.ts,*.test.tsx,*.spec.ts,*.d.ts,*.stories.tsx"
RULES_FILE="AGENTS.md"

Python Project

# .gga
PROVIDER="lmstudio:codellama"
FILE_PATTERNS="*.py"
EXCLUDE_PATTERNS="*_test.py,test_*.py,conftest.py,__pycache__/*"
RULES_FILE=".coding-standards.md"

Go Project

# .gga
PROVIDER="gemini"
FILE_PATTERNS="*.go"
EXCLUDE_PATTERNS="*_test.go,mock_*.go,*_mock.go"

Full-Stack Monorepo

# .gga
PROVIDER="claude"
FILE_PATTERNS="*.ts,*.tsx,*.py,*.go"
EXCLUDE_PATTERNS="*.test.*,*_test.*,*.mock.*,*.d.ts,dist/*,build/*"

πŸ”„ How It Works

git commit -m "feat: add feature"
    β”‚
    β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Pre-commit Hook (gga run) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    β”‚
    β”œβ”€β”€β–Ά 1. Load config from .gga
    β”‚
    β”œβ”€β”€β–Ά 2. Validate provider is installed
    β”‚
    β”œβ”€β”€β–Ά 3. Check AGENTS.md exists
    β”‚
    β”œβ”€β”€β–Ά 4. Get staged files matching FILE_PATTERNS
    β”‚       (excluding EXCLUDE_PATTERNS)
    β”‚
    β”œβ”€β”€β–Ά 5. Read coding rules from AGENTS.md
    β”‚
    β”œβ”€β”€β–Ά 6. Build prompt: rules + file contents
    β”‚
    β”œβ”€β”€β–Ά 7. Send to AI provider (with timeout + progress)
    β”‚       (claude/gemini/codex/opencode/ollama/lmstudio/github)
    β”‚
    └──▢ 8. Parse response
            β”‚
            β”œβ”€β”€ "STATUS: PASSED" ──▢ βœ… Commit proceeds
            β”‚
            └── "STATUS: FAILED" ──▢ ❌ Commit blocked
                                       (shows violation details)

🚫 Bypass Review

Sometimes you need to commit without review:

# Skip pre-commit hook entirely
git commit --no-verify -m "wip: work in progress"

# Short form
git commit -n -m "hotfix: urgent fix"

πŸ”— Integrations

Gentleman Guardian Angel works standalone with native git hooks, but you can also integrate it with popular hook managers.

Native Git Hook (Default)

This is what gga install does automatically:

# .git/hooks/pre-commit
#!/usr/bin/env bash
gga run || exit 1

Husky (Node.js projects)

Husky is popular in JavaScript/TypeScript projects.

Setup with Husky v9+

# Install husky
npm install -D husky

# Initialize husky
npx husky init

Edit .husky/pre-commit:

#!/usr/bin/env bash

# Run Gentleman Guardian Angel
gga run || exit 1

# Your other checks (optional)
npm run lint
npm run typecheck

With lint-staged (review only staged files)

# Install dependencies
npm install -D husky lint-staged

package.json:

{
  "scripts": {
    "prepare": "husky"
  },
  "lint-staged": {
    "*.{ts,tsx,js,jsx}": ["eslint --fix", "prettier --write"]
  }
}

.husky/pre-commit:

#!/usr/bin/env bash

# AI Review first (uses git staged files internally)
gga run || exit 1

# Then lint-staged for formatting
npx lint-staged

pre-commit (Python projects)

pre-commit is the standard for Python projects.

Setup

# Install pre-commit
pip install pre-commit

# Or with brew
brew install pre-commit

Create .pre-commit-config.yaml:

repos:
  # Gentleman Guardian Angel (runs first)
  - repo: local
    hooks:
      - id: gga
        name: Gentleman Guardian Angel
        entry: gga run
        language: system
        pass_filenames: false
        stages: [pre-commit]

  # Your other hooks
  - repo: https://github.com/psf/black
    rev: 24.4.2
    hooks:
      - id: black

  - repo: https://github.com/pycqa/flake8
    rev: 7.0.0
    hooks:
      - id: flake8

  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.10.0
    hooks:
      - id: mypy

Install the hooks:

pre-commit install

Running manually

# Run all hooks
pre-commit run --all-files

# Run only AI review
pre-commit run gga

Lefthook (Fast, language-agnostic)

Lefthook is a fast Git hooks manager written in Go.

Setup

# Install
brew install lefthook

# Or with npm
npm install -D lefthook

Create lefthook.yml:

pre-commit:
  parallel: false
  commands:
    ai-review:
      run: gga run
      fail_text: "Gentleman Guardian Angel failed. Fix violations before committing."

    lint:
      glob: "*.{ts,tsx,js,jsx}"
      run: npm run lint

    typecheck:
      run: npm run typecheck

Install hooks:

lefthook install

CI/CD Integration

You can also run Gentleman Guardian Angel in your CI pipeline:

GitHub Actions

# .github/workflows/ai-review.yml
name: Gentleman Guardian Angel

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install Gentleman Guardian Angel
        run: |
          git clone https://github.com/Gentleman-Programming/gentleman-guardian-angel.git /tmp/gga
          chmod +x /tmp/gga/bin/gga
          echo "/tmp/gga/bin" >> $GITHUB_PATH

      - name: Install Claude CLI
        run: |
          # Install your preferred provider CLI
          npm install -g @anthropic-ai/claude-code
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

      - name: Run AI Review
        run: |
          # Review all files changed in the PR
          gga run --pr-mode

          # Or with diffs only (faster, cheaper)
          # gga run --pr-mode --diff-only

GitLab CI

# .gitlab-ci.yml
gga:
  stage: test
  image: ubuntu:latest
  before_script:
    - apt-get update && apt-get install -y git curl
    - git clone https://github.com/Gentleman-Programming/gentleman-guardian-angel.git /opt/gga
    - export PATH="/opt/gga/bin:$PATH"
    # Install your provider CLI here
  script:
    - git diff --name-only $CI_MERGE_REQUEST_DIFF_BASE_SHA | xargs git add
    - gga run
  only:
    - merge_requests

πŸ› Troubleshooting

"Provider not found"

# Check if your provider CLI is installed and in PATH
which claude   # Should show: /usr/local/bin/claude or similar
which gemini
which codex
which ollama

# Test if the provider works
echo "Say hello" | claude --print

# For LM Studio, check if the API is accessible
curl http://localhost:1234/v1/models

"Rules file not found"

The tool requires a rules file to know what to check:

# Create your rules file
touch AGENTS.md

# Add your coding standards
echo "# My Coding Standards" > AGENTS.md
echo "- No console.log in production" >> AGENTS.md

"Ambiguous response" in Strict Mode

The AI must respond with STATUS: PASSED or STATUS: FAILED as the first line. If it doesn't:

  1. Try Claude (most reliable at following instructions)
  2. Check your rules file isn't confusing the AI
  3. Temporarily disable strict mode: STRICT_MODE="false"

Slow reviews on large files

The tool sends full file contents. For better performance:

# Add large/generated files to exclude
EXCLUDE_PATTERNS="*.min.js,*.bundle.js,dist/*,build/*,*.generated.ts"

GitHub Models setup

# 1. Install GitHub CLI
brew install gh

# 2. Authenticate
gh auth login

# 3. Configure GGA
echo 'PROVIDER="github:gpt-4o"' > .gga

# Available models: https://github.com/marketplace/models

Timeout issues

If reviews are timing out (exit code 124):

# Increase timeout (default: 300s)
TIMEOUT="600"          # In .gga config
GGA_TIMEOUT=600 gga run  # Or via environment variable

# Review fewer files at once
EXCLUDE_PATTERNS="*.min.js,*.bundle.js,dist/*"

LM Studio connection issues

If you get "Failed to connect to LM Studio" errors:

  1. Ensure LM Studio is running and the API server is enabled
  2. Check the API port in LM Studio settings (default: 1234)
  3. Verify the host setting:
    # Default
    LMSTUDIO_HOST="http://localhost:1234/v1"
    
    # Custom port
    LMSTUDIO_HOST="http://localhost:8080/v1"
  4. Test the connection:
    curl http://localhost:1234/v1/models

πŸ§ͺ Development

Project Structure

gentleman-guardian-angel/
β”œβ”€β”€ bin/
β”‚   └── gga                          # Main CLI script
β”œβ”€β”€ lib/
β”‚   β”œβ”€β”€ providers.sh                 # AI provider implementations
β”‚   β”œβ”€β”€ cache.sh                     # Smart caching logic
β”‚   └── pr_mode.sh                   # PR review mode functions
β”œβ”€β”€ spec/                            # ShellSpec test suite
β”‚   β”œβ”€β”€ spec_helper.sh               # Test setup and helpers
β”‚   β”œβ”€β”€ unit/
β”‚   β”‚   β”œβ”€β”€ cache_spec.sh            # Cache unit tests
β”‚   β”‚   β”œβ”€β”€ providers_spec.sh        # Provider unit tests
β”‚   β”‚   β”œβ”€β”€ github_models_spec.sh    # GitHub Models tests
β”‚   β”‚   β”œβ”€β”€ pr_mode_spec.sh          # PR mode tests
β”‚   β”‚   β”œβ”€β”€ timeout_spec.sh          # Timeout/spinner tests
β”‚   β”‚   └── status_parsing_spec.sh   # STATUS parsing tests
β”‚   └── integration/
β”‚       β”œβ”€β”€ commands_spec.sh         # CLI integration tests
β”‚       β”œβ”€β”€ ollama_spec.sh           # Ollama integration (local)
β”‚       └── github_models_spec.sh    # GitHub Models integration (local)
β”œβ”€β”€ Makefile                         # Development commands
β”œβ”€β”€ .shellspec                       # Test runner config
β”œβ”€β”€ install.sh                       # Manual installer
β”œβ”€β”€ uninstall.sh                     # Uninstaller
└── README.md

Running Tests

GGA uses ShellSpec for testing - a BDD-style testing framework for shell scripts.

# Install dependencies (once)
brew install shellspec shellcheck

# Run all tests
make test

# Run specific test suites
make test-unit        # Unit tests only
make test-integration # Integration tests only

# Lint shell scripts with shellcheck
make lint

# Run all checks before commit (lint + tests)
make check

Test Coverage

Module Tests Description
cache.sh 26 Hash functions, cache validation, file caching
providers.sh 98 All providers, routing, validation, security
github_models 16 GitHub Models provider, API, auth, error handling
pr_mode 26 Base branch detection, PR files, diff, prompt building
timeout 19 Timeout wrapper, spinner, provider routing
status_parsing 14 STATUS: PASSED/FAILED parsing edge cases
Integration 34+ CLI commands, Ollama, GitHub Models (local)
Total 174 Full coverage of core functionality

Adding New Tests

# Create a new spec file
touch spec/unit/my_feature_spec.sh

# Run only your new tests
shellspec spec/unit/my_feature_spec.sh

πŸ“‹ Changelog

v2.7.0 (Latest)

  • βœ… feat: Timeout & progress feedback for AI provider calls (#35, based on PR #20 by @ramarivera)
    • Configurable TIMEOUT (default: 300s) with GGA_TIMEOUT env override
    • Visual spinner in TTY mode, periodic text updates in CI/pipes
    • Exit code 124 on timeout with troubleshooting suggestions
    • Generic fallback for unknown/future providers
    • 19 new tests
  • βœ… feat: GitHub Models provider (#36, based on PR #3 by @Kyonax)
    • PROVIDER="github:<model>" β€” access GPT-4o, DeepSeek R1, Grok 3, Phi-4, LLaMA, etc.
    • Auth via gh auth token β€” no extra API keys needed
    • Uses python3 for safe JSON (no jq dependency)
    • 16 new tests
  • βœ… feat: PR review mode (#37, based on PR #30 by @Jose-cd)
    • --pr-mode: review all files changed in the full PR range
    • --diff-only: with --pr-mode, send only diffs (faster, cheaper)
    • Auto-detects base branch (main/master/develop) with PR_BASE_BRANCH config override
    • 26 new tests
  • βœ… 174 tests total, 0 failures

v2.6.1

  • βœ… fix: Relaxed STATUS parsing to handle AI preamble text (#18, PR #19)
    • Search for STATUS in first 15 lines instead of requiring line 1
    • Accept markdown formatting (**STATUS: PASSED**)
    • Works with AI agents that have system-wide instruction files (AGENTS.md, CLAUDE.md)
  • βœ… 14 new tests for STATUS parsing edge cases
  • βœ… 161 tests total

v2.6.0

  • βœ… feat: Commit message validation support (PR #17, based on #11 by @ramarivera)
    • gga install --commit-msg installs commit-msg hook instead of pre-commit
    • Commit message is automatically included in AI review when available
    • No config needed - behavior is automatic based on context
  • βœ… fix: Read from staging area (git show :file) to prevent index corruption (#15, #16)
    • Fixes race conditions when files are modified after staging
    • Works correctly with lint-staged, prettier, and other tools
  • βœ… feat: Signal handling for graceful cleanup on interruption
  • βœ… gga uninstall now handles both pre-commit and commit-msg hooks
  • βœ… 147 tests (17 new for commit-msg and staging area fixes)

v2.5.1

  • βœ… fix(gemini): Use -p flag for non-interactive prompt passing - fixes exit code 41 in CI
  • βœ… fix(opencode): Use positional argument instead of stdin pipe per documentation
  • βœ… Both providers now work correctly in CI/non-interactive environments

v2.5.0

  • βœ… feat: OpenCode provider support (PR #4 by @ramarivera)
    • PROVIDER="opencode" for default model
    • PROVIDER="opencode:model_name" for specific models
  • βœ… Added CONTRIBUTING.md with development guide
  • βœ… 130 tests (12 new for OpenCode)

v2.4.0

  • βœ… feat: CI mode (--ci flag) for GitHub Actions/GitLab CI
    • Reviews files from last commit (HEAD~1..HEAD) instead of staged files
    • Cache automatically disabled in CI mode
  • βœ… 118 tests (6 new for CI mode)

v2.3.0

  • βœ… Fixed Ollama ANSI escape codes breaking STATUS parsing (#6)
  • βœ… New execute_ollama_api() using curl for clean JSON responses
  • βœ… Fallback execute_ollama_cli() with ANSI stripping
  • βœ… Security validation for OLLAMA_HOST
  • βœ… Worktree support and improved hook install/uninstall (PR #10 by @ramarivera)
  • βœ… Best practices docs for AGENTS.md rules file
  • βœ… GitHub Actions CI pipeline (lint, unit tests, integration tests)
  • βœ… Expanded test suite to 104 tests

v2.2.0

  • βœ… Added comprehensive test suite with 68 tests
  • βœ… Unit tests for cache.sh and providers.sh
  • βœ… Integration tests for all CLI commands
  • βœ… Added Makefile with test, lint, check targets
  • βœ… Fixed shellcheck warnings

v2.1.0

  • βœ… Smart caching system - skip unchanged files
  • βœ… Auto-invalidation when AGENTS.md or .gga changes
  • βœ… Cache commands: status, clear, clear-all
  • βœ… --no-cache flag to bypass caching

v2.0.0

  • βœ… Renamed to Gentleman Guardian Angel (gga)
  • βœ… Auto-migration from legacy ai-code-review hooks
  • βœ… Homebrew tap distribution

v1.0.0

  • βœ… Initial release with Claude, Gemini, Codex, Ollama support
  • βœ… File patterns and exclusions
  • βœ… Strict mode for CI/CD

🀝 Contributing

Contributions are welcome! Some ideas:

  • Add more providers (Copilot, Codeium, etc.)
  • Support for .gga.yaml format
  • Caching to avoid re-reviewing unchanged files βœ… Done in v2.1.0
  • Add test suite βœ… Done in v2.2.0
  • CI mode for GitHub Actions/GitLab βœ… Done in v2.4.0
  • OpenCode provider βœ… Done in v2.5.0 (by @ramarivera)
  • Timeout & progress feedback βœ… Done in v2.7.0 (based on @ramarivera)
  • GitHub Models provider βœ… Done in v2.7.0 (based on @Kyonax)
  • PR review mode βœ… Done in v2.7.0 (based on @Jose-cd)
  • Configurable temperature per provider
  • GitHub Action version
  • Output formats (JSON, SARIF for IDE integration)
# Fork, clone, and submit PRs!
git clone https://github.com/Gentleman-Programming/gentleman-guardian-angel.git
cd gentleman-guardian-angel

# Run tests before submitting
make check

πŸ“„ License

MIT Β© 2024


Built with πŸ§‰ by developers who got tired of repeating the same code review comments

About

πŸ˜‡ Gentleman Guardian Angel (gga) - Provider-agnostic code review using AI. Use Claude, Gemini, Codex, Ollama to enforce your coding standards.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published