Skip to content

JNZader/ghagga

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

692 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GHAGGA Logo

GHAGGA

AI code review that learns your project — multi-agent orchestration, 17 static-analysis tools, and persistent review memory.

npm version CI status License: MIT Node.js >= 20 TypeScript strict

Website · Documentation · Live Dashboard · Install GitHub App

Read this in: English · Español


GHAGGA is a production AI code-review system — not a prompt wrapper. One review engine, four delivery surfaces: a hosted GitHub App, a GitHub Action, a CLI for local pre-push review, and a fully self-hosted Docker deployment.

What makes it different:

  • Static analysis runs first. 17 deterministic tools (Semgrep, Trivy, Gitleaks, Ruff, clippy, …) catch known issues before a single LLM token is spent. Findings are injected into the review prompt so the model spends its attention on logic and architecture, not lint.
  • It remembers. Past decisions, bugfixes, and patterns persist across reviews (PostgreSQL, SQLite, or Engram) and feed back into future ones — with full-text search, strength decay, and privacy stripping.
  • Five orchestration strategies. From a single fast pass to multi-agent consensus voting, chosen per review by the cost/confidence tradeoff you want.
  • Forge-agnostic core. The review engine speaks in provider-neutral ports; the CLI posts findings back to GitHub pull requests (--pr) and GitLab merge requests (--mr), with Gitea modeled in the same abstraction.
  • No runner infrastructure. Server mode injects an inline GitHub Actions workflow into each target repo and dispatches it — heavy analysis runs on the repo's own free CI minutes, secured with per-dispatch HMAC secrets.

By the Numbers

Production code ~62,000 lines of strict TypeScript across 8 workspaces
Test code ~73,000 lines — more test code than production code
Test suite 4,500+ test cases in 231 test files (Vitest), plus mutation testing with Stryker
Static analysis 17 tools — 7 always-on, 10 auto-detected by stack
Review modes 5 orchestration strategies (single-pass → multi-agent consensus)
Distribution GitHub App (SaaS) · GitHub Action · npm CLI · self-hosted Docker

Architecture

A reusable core owns the review pipeline; thin adapters translate transport and IO. ghagga-core knows nothing about HTTP, dashboard auth, or terminal rendering, and ghagga-forge keeps it from knowing whether it's talking to GitHub, GitLab, or Gitea.

graph TB
  subgraph Distribution["Distribution Layer"]
    Server["Server<br/>Hono + BullMQ"]
    Action["GitHub Action"]
    CLI["CLI"]
  end

  subgraph Worker["Async Worker"]
    BullMQ["BullMQ Worker<br/>Review Jobs"]
  end

  subgraph Inline["Inline Workflow (per target repo)"]
    InlineYml[".github/workflows/ghagga.yml<br/>injected by server"]
    InlineTools["Static Analysis<br/>on the repo's own runner"]
  end

  subgraph Core["ghagga-core"]
    SA["Static Analysis<br/>17-tool registry"]
    Agents["AI Agents<br/>5 review modes"]
    Memory["Memory<br/>Search / Persist / Decay / Versioning"]
    Scope["Scope<br/>Tree-sitter symbol extraction"]
  end

  subgraph Forge["ghagga-forge"]
    Ports["Forge-agnostic ports<br/>GitHub / GitLab / Gitea"]
  end

  subgraph DB["ghagga-db"]
    PG["PostgreSQL 16<br/>+ tsvector FTS"]
    Crypto["AES-256-GCM<br/>Encryption"]
  end

  Server -- enqueue --> BullMQ
  BullMQ --> Core
  BullMQ -- "inject + workflow_dispatch" --> InlineYml
  InlineYml --> InlineTools
  InlineTools -- "HMAC-signed callback" --> Server
  Action --> Core
  CLI --> Core
  Core --> Forge
  Core --> DB
Loading

Every review follows the same pipeline, regardless of entry point:

flowchart LR
  DIFF["diff"] --> VAL["validate"]
  VAL --> PARSE["parse & filter"]
  PARSE --> STACKS["detect stacks"]
  STACKS --> BUDGET["token budget"]
  BUDGET --> SA["static analysis + memory search"]
  SA --> AGENTS["agent execution"]
  AGENTS --> MERGE["merge findings"]
  MERGE --> MEM["persist memory"]
  MEM --> RESULT["ReviewResult"]
Loading

The pipeline degrades gracefully: missing tools, unreachable memory, or an unconfigured LLM never hard-fail a review.

Quick Start

GitHub App (hosted) — install the App, configure your provider chain in the dashboard, open a PR.

GitHub Action:

# .github/workflows/ghagga.yml
name: Code Review
on:
  pull_request:
    types: [opened, synchronize, reopened]
permissions:
  pull-requests: write
jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: JNZader/ghagga@v3

CLI — review local changes before they hit CI:

npm install -g ghagga
ghagga login                    # authenticate with GitHub (free AI models)
ghagga review --staged          # review staged changes
ghagga review --mode consensus  # multi-agent vote
ghagga review --pr 42           # review a GitHub PR and post findings back
ghagga review --mr 42           # review a GitLab merge request and post findings back
ghagga health --top 10          # project health score
ghagga hooks install            # pre-commit + commit-msg hooks

Self-hosted — full stack with server, worker, PostgreSQL, and Redis:

git clone https://github.com/JNZader/ghagga.git
cd ghagga
cp .env.example .env
docker compose up -d

Full setup guides: Quick Start · GitHub Action · CLI · Configuration

Review Modes

Five strategies with explicit cost/confidence tradeoffs:

Mode How it works Token cost Best for
simple Single LLM pass ~1x Small PRs, fast feedback
consensus 3 stances (advocate / critic / observer) + algorithmic vote ~3x High-confidence approval decisions
fan-out 5 independent lenses (security, typing, performance, a11y, error handling) merged by severity ~5x Broad category coverage, custom lenses
workflow 5 specialists in parallel + synthesis step ~6x Thorough multi-angle reviews
diagnostic Hypothesis-driven analysis with adaptive follow-up queries varies Digging into suspicious changes

fan-out is the multi-agent workhorse: independent lenses review the same diff in parallel, then findings are merged by severity into one result. Custom lenses can be supplied with --lenses and --lens-dir.

flowchart TD
  DIFF["PR diff + memory context"] --> FO["fan-out mode"]
  FO --> SEC["Security lens"]
  FO --> TYP["Typing lens"]
  FO --> PERF["Performance lens"]
  FO --> A11Y["a11y lens"]
  FO --> ERR["Error-handling lens"]
  SEC --> MERGE["Merge by severity"]
  TYP --> MERGE
  PERF --> MERGE
  A11Y --> MERGE
  ERR --> MERGE
  MERGE --> RESULT["Unified ReviewResult + health score"]
Loading

Static Analysis — Layer 0

Deterministic checks run before the expensive stochastic layer. All tools are optional and skipped gracefully when missing.

  • Always-on (7): Semgrep, Trivy, Gitleaks, ShellCheck, CPD, markdownlint, Lizard
  • Auto-detected by stack (10): Ruff + Bandit (Python), golangci-lint (Go), Biome (JS/TS), clippy (Rust), PMD (Java), Psalm (PHP), Hadolint (Docker), zizmor (GitHub Actions), SonarQube (via MCP)

The GitHub Action bundles the 16 tools that run directly on the runner; SonarQube is available in server mode over MCP, for 17 total in the full registry.

In server mode, this layer runs as an inline workflow injected into the target repo — no separate runner repository to provision, no RAM-hungry analysis on the API server. Callbacks are verified with per-dispatch HMAC-SHA256 secrets under a TTL.

Project Memory

The part that makes reviews compound over time:

  • Search before review — relevant past observations are injected into prompts as context.
  • Persist after review — significant findings are stored as typed observations (decision, pattern, bugfix, architecture, …) with deduplication.
  • Strength decay — stale observations fade out of context instead of polluting it forever.
  • Versioning — git-like branch / snapshot / merge / rollback over memory state.
  • Privacy stripping — 16 redaction patterns (API keys, provider tokens, JWTs, PEM/SSH keys, env secrets, URL-embedded credentials) run before any write.

Backends: PostgreSQL (tsvector + ts_rank) for server mode, SQLite (FTS5 + BM25) for CLI/Action, or Engram over HTTP.

Security

Control Implementation
Provider API keys AES-256-GCM encryption at rest, per-installation keys
GitHub webhooks HMAC-SHA256 with constant-time comparison
Runner callbacks Per-dispatch derived HMAC secrets + embedded-timestamp TTL
Memory writes Privacy stripping (16 redaction patterns)
Outbound gateway URLs SSRF guard — IP-range + DNS validation at persist time, re-validated at execution time
LLM prompts Trust boundary — repo content, memory, and prior findings framed and sanitized as untrusted input
Job queue Credentials never enter Redis payloads — workers re-fetch encrypted keys from PostgreSQL
Injected workflow permissions: contents: read, secret masking, output normalization
Test coverage Dedicated security suite: encryption tamper detection, HMAC correctness, no-secret-logging, no-eval, prototype-pollution checks

Vulnerability reports: see SECURITY.md.

Monorepo

ghagga/
├── packages/
│   ├── core/        # Review engine: agents, 17-tool registry, memory, tree-sitter scoping
│   ├── db/          # Drizzle schema, PostgreSQL queries, AES-256-GCM crypto, migrations
│   ├── forge/       # Forge-agnostic ports & domain types (GitHub / GitLab / Gitea)
│   └── types/       # Shared API contracts
├── apps/
│   ├── server/      # Hono API + BullMQ workers + GitHub App integration
│   ├── action/      # GitHub Action runtime (SQLite memory via @actions/cache)
│   ├── cli/         # npm CLI: review, memory, hooks, health, audit, feedback
│   └── dashboard/   # React 19 SPA: provider chains, review history, memory browser
├── templates/       # Inline static-analysis workflow template
└── docs/            # Documentation site (GitHub Pages)

Published packages: ghagga (CLI), ghagga-core, ghagga-db, and ghagga-forge.

Stack: TypeScript (strict) · Hono · BullMQ + Redis · PostgreSQL 16 + Drizzle · React 19 + Vite + Tailwind 4 · Vitest + Stryker · Biome · pnpm + Turborepo

LLM providers: everything routes through a provider chain with ordered fallback — gateway (any model via mcp-llm-bridge), cli-bridge (local Claude / Gemini / Copilot CLIs), or ollama (local models).

Engineering Notes

A few decisions worth calling out:

  • Core/adapter split. The review engine is transport- and forge-agnostic; server, Action, and CLI are thin IO translators. Adding a delivery mode doesn't touch the pipeline.
  • Tests outweigh production code (~73k vs ~62k LOC), with mutation testing (Stryker) guarding core, server, and Action against assertion-free tests.
  • v2 was a real rewrite, not a patch: v1's Deno + Node + Python sprawl collapsed into a single-runtime Node monorepo with async orchestration (BullMQ), a 17-tool registry (up from Semgrep-only), and an actually-used memory system.
  • Graceful degradation everywhere. Missing static tools, unreachable memory backends, blocked workflow injection — every layer falls back instead of failing the review.

Development

pnpm install
docker compose up postgres redis -d
cp .env.example .env
pnpm --filter ghagga-db db:push
pnpm exec turbo typecheck build test

Deep dives live in the documentation site: Architecture · Memory System · API Reference · Database Schema

Contributing

Contributions are welcome. Start with CONTRIBUTING.md and the Code of Conduct. Security issues go through SECURITY.md, not public issues.

Credits

Inspired by Gentleman Guardian Angel (GGA) and Engram by Gentleman Programming.

License

MIT. See LICENSE.

About

AI code review that learns your project — GitHub App, Action, CLI & self-hosted. 17 static-analysis tools (Semgrep, Trivy, Gitleaks, Ruff…), persistent review memory, multi-agent orchestration, SARIF export.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages