- TypeScript 92.7%
- JavaScript 5.7%
- Dockerfile 1.1%
- Just 0.3%
- Nix 0.2%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .github/workflows | ||
| docs | ||
| evals | ||
| scripts | ||
| src | ||
| templates | ||
| tests | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| .gitlab-ci.yml | ||
| AGENTS.md | ||
| bun.lock | ||
| Dockerfile | ||
| flake.lock | ||
| flake.nix | ||
| justfile | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tsup.config.ts | ||
| vitest.config.ts | ||
Hodor
Agentic code reviewer for GitHub PRs, GitLab MRs, Gitea/Forgejo PRs, and local diffs.
Hodor uses read-only tools to analyze code changes, identify bugs, and post structured reviews.
Install
# Just run it (zero install, always latest)
npx @mrkaran/hodor <PR_URL>
# Or install globally
npm install -g @mrkaran/hodor
Docker images are also available at ghcr.io/mr-karan/hodor:latest for CI environments.
Setup
# Set an API key for your LLM provider
export ANTHROPIC_API_KEY=sk-... # Anthropic (default)
export OPENAI_API_KEY=sk-... # OpenAI
export OPENROUTER_API_KEY=sk-or-... # OpenRouter (e.g., Kimi K2.6)
export AWS_PROFILE=default # AWS Bedrock (no API key needed)
# For posting reviews as comments
gh auth login # GitHub
glab auth login # GitLab
# For Gitea/Forgejo private repos or posting comments
export GITEA_TOKEN=your-token # or FORGEJO_TOKEN
Usage
# Review a GitHub PR
npx @mrkaran/hodor https://github.com/owner/repo/pull/123
# Review a GitLab MR (including self-hosted)
npx @mrkaran/hodor https://gitlab.example.com/org/project/-/merge_requests/42
# Review a Gitea or Forgejo PR
npx @mrkaran/hodor https://git.example.com/owner/repo/pulls/123
# Post the review as a PR/MR comment
npx @mrkaran/hodor <PR_URL> --post
# Use a different model
npx @mrkaran/hodor <PR_URL> --model openai/gpt-5
npx @mrkaran/hodor <PR_URL> --model bedrock/converse/anthropic.claude-sonnet-4-5-v2
# Extended reasoning for complex PRs
npx @mrkaran/hodor <PR_URL> --reasoning-effort high
# Force a full review of the entire branch (ignore previous incremental reviews)
npx @mrkaran/hodor <PR_URL> --full
# Verbose mode (watch the agent think)
npx @mrkaran/hodor <PR_URL> -v
If you installed globally with
npm install -g, replacenpx @mrkaran/hodorwithhodor.
Review instructions
Choose the default review profile, a custom security profile, or a one-off focus for a review:
# Default profile
npx @mrkaran/hodor <PR_URL>
# Custom profile that replaces the bundled default
npx @mrkaran/hodor <PR_URL> \
--review-instructions ./review-profiles/security.md
# One-off request added after the selected profile
npx @mrkaran/hodor <PR_URL> \
--additional-instructions "Focus on authorization changes in the admin API."
A review profile applies to the whole run. A custom profile replaces the bundled default profile. Additional instructions are additive. Repository-specific rules remain in .agents/skills/ and are used when relevant. Hodor's review rules take precedence if these inputs conflict.
See Review instructions for complete security and code-quality profiles, local and CI examples, migration guidance, and file validation troubleshooting.
Local Mode
Review local git changes without a PR URL. Useful for pre-push reviews, Bitbucket PRs, or any git repo.
# Review uncommitted changes against origin/main (default)
npx @mrkaran/hodor --local
# Review against a specific branch or ref
npx @mrkaran/hodor --local --diff-against develop
npx @mrkaran/hodor --local --diff-against HEAD~3
# Review a feature branch against main
git checkout feature-branch
npx @mrkaran/hodor --local --diff-against origin/main
# Use a specific workspace directory
npx @mrkaran/hodor --local --workspace /path/to/repo
# Combine with other flags
npx @mrkaran/hodor --local --diff-against origin/main --model openai/gpt-5 -v
Local mode:
- Includes uncommitted changes (staged + unstaged), not just commits
- Auto-resolves to the git repo root (works from subdirectories)
- Skips PR metadata fetching and workspace cloning
--postis disabled (no remote to post to)
CLI Flags
| Flag | Default | Description |
|---|---|---|
--model |
anthropic/claude-sonnet-4-5-20250929 |
LLM model as provider/model-id. Recommended: Anthropic, OpenAI, Bedrock, OpenRouter. Other configured providers such as Mistral, Gemini, xAI, and Groq are best-effort. See docs/MODELS.md. |
--reasoning-effort |
None | Extended thinking: low, medium, high |
--ultrathink |
Off | Maximum reasoning effort |
--full |
Off | Review the entire source-vs-target diff from scratch, ignoring previous hodor reviews (disables incremental mode) |
--target-branch |
None | Override the target branch to diff against under --full (default: the PR/MR's target branch) |
--local |
Off | Review local git changes (no PR URL required) |
--diff-against |
origin/main |
Git ref to diff against in --local mode |
--post |
Off | Post review as a comment on the PR/MR |
--review-style |
hybrid |
GitLab posting style: rolling summary, inline, or both with hybrid |
--code-quality |
None | Write a Code Quality report containing current and unresolved Hodor findings |
--commit-status |
Off | Post a pass/fail status based on all unresolved Hodor findings |
--require-delivery |
Off | Exit non-zero if requested comments, statuses, or artifacts are not delivered |
--fail-on-priority |
None | Exit non-zero for findings at or above P0, P1, P2, or P3 |
--review-instructions |
None | Read a custom review profile from a file. It replaces the bundled default profile for this run. |
--additional-instructions |
None | Add one-off review instructions after the selected profile. |
--workspace |
Temp dir | Workspace directory (reuse for faster multi-PR reviews) |
--bedrock-tags |
None | JSON cost allocation tags for AWS Bedrock |
--prometheus-push |
None | Push review metrics to a Prometheus Pushgateway or VictoriaMetrics import endpoint |
-v, --verbose |
Off | Stream agent reasoning and tool calls |
Environment Variables
| Variable | Purpose |
|---|---|
ANTHROPIC_API_KEY |
Claude API key |
OPENAI_API_KEY |
OpenAI API key |
OPENROUTER_API_KEY |
OpenRouter API key (for openrouter/... models, e.g. openrouter/moonshotai/kimi-k2.6) |
| Provider-specific keys | For best-effort pi-ai providers, use the env var pi-ai expects (e.g. MISTRAL_API_KEY, GEMINI_API_KEY, XAI_API_KEY, GROQ_API_KEY) |
LLM_API_KEY |
Generic fallback (when provider-specific key is not set) |
GITHUB_TOKEN / GITLAB_TOKEN |
Post comments to GitHub PRs / GitLab MRs (with --post) |
GITEA_TOKEN / FORGEJO_TOKEN |
Read private repos and post comments on Gitea/Forgejo PRs |
GITEA_HOST / FORGEJO_HOST |
Hostname for Gitea/Forgejo when not inferable from a full PR URL |
AWS_PROFILE or AWS_ACCESS_KEY_ID |
AWS Bedrock auth (no API key needed) |
See docs/MODELS.md for the full model/provider matrix and docs/OPENROUTER.md for an end-to-end Kimi K2.6 example.
Gitea / Forgejo
Hodor supports Gitea and Forgejo pull request URLs in this format:
npx @mrkaran/hodor https://git.example.com/owner/repo/pulls/123
For public repositories, metadata fetching may work without a token. Set GITEA_TOKEN or FORGEJO_TOKEN for private repositories, higher API limits, and --post:
export GITEA_TOKEN=your-token
npx @mrkaran/hodor https://git.example.com/owner/repo/pulls/123 --post
Fork PRs are checked out from the PR source repository when Gitea exposes the source clone URL. If the source branch or fork has been deleted, checkout will fail with a workspace error.
CI/CD
Metrics in CI
Hodor can push per-review metrics at the end of a CI run to either a Prometheus Pushgateway base URL or a VictoriaMetrics Prometheus import endpoint (/api/v1/import/prometheus):
hodor "$MR_OR_PR_URL" --prometheus-push "$METRICS_PUSH_URL"
In CI, set METRICS_PUSH_URL as a secret/variable and add --prometheus-push "$METRICS_PUSH_URL" to the Hodor command. Metrics are best-effort: push failures are logged as warnings and do not fail the review job.
Each metric is labeled with platform, model, verdict, outcome, and for PR/MR URLs also project (owner/repo). MR/PR numbers are deliberately excluded to avoid unbounded time-series cardinality. Exported metrics include token usage, cache read/write tokens, cache hit ratio, cost, turns, tool calls, duration, and findings by priority (P0 to P3). A generic Grafana dashboard is available in docs/grafana/.
GitHub Actions
name: Hodor Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
container: ghcr.io/mr-karan/hodor:latest
steps:
- name: Run Hodor
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
METRICS_PUSH_URL: ${{ secrets.METRICS_PUSH_URL }} # optional
run: |
EXTRA_ARGS=""
if [ -n "${METRICS_PUSH_URL:-}" ]; then EXTRA_ARGS="--prometheus-push $METRICS_PUSH_URL"; fi
bun run /app/dist/cli.js "https://github.com/${{ github.repository }}/pull/${{ github.event.pull_request.number }}" --post $EXTRA_ARGS
GitLab CI
# .gitlab-ci.yml
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
hodor-review:
stage: test
image:
name: ghcr.io/mr-karan/hodor:latest
entrypoint: [""]
variables:
HODOR_MODEL: "anthropic/claude-sonnet-4-5-20250929"
before_script:
- glab auth login --hostname $CI_SERVER_HOST --token $GITLAB_TOKEN
script:
- MR_URL="${CI_PROJECT_URL}/-/merge_requests/${CI_MERGE_REQUEST_IID}"
- |
EXTRA_ARGS=""
if [ -n "${METRICS_PUSH_URL:-}" ]; then EXTRA_ARGS="--prometheus-push $METRICS_PUSH_URL"; fi
bun run /app/dist/cli.js "$MR_URL" --model "$HODOR_MODEL" --post --code-quality gl-code-quality-report.json --commit-status $EXTRA_ARGS
artifacts:
expose_as: "Hodor findings"
paths:
- gl-code-quality-report.json
reports:
codequality: gl-code-quality-report.json
when: always
allow_failure: true
timeout: 15m
This posts actionable findings inline, updates one rolling summary note with collapsed run metrics, sets a commit status from all unresolved Hodor findings, and exposes the cumulative Code Quality report from the MR.
See AUTOMATED_REVIEWS.md for advanced workflows.
Token Optimization
Hodor automatically optimizes token usage:
- Diff embedding: For PRs under 200KB, the diff is embedded directly in the prompt, cutting agent turns from ~60 to ~5.
- Incremental reviews: On re-runs, only reviews changes since the last hodor comment. After a force-push or rebase, Hodor compares the last reviewed snapshot directly with the current HEAD instead of reviewing the whole MR again.
- Identical-HEAD reuse: Successful summaries include a versioned, compressed review payload. Pipeline retries with the same HEAD, model, reasoning request, review profile, and additional instructions reuse that result while still regenerating artifacts and retrying delivery.
- Adaptive reasoning: Models that default to
xhighusehighfor routine small and incremental diffs, while risky, large, explicitly configured, and--fullreviews retain the requested depth. - Focused exploration: Embedded diffs include a changed-file manifest and direct the agent toward bounded context reads without limiting how far it may investigate.
- Compaction: Hodor auto-summarizes older conversation turns when context grows too large.
Pass --full to bypass incremental mode and identical-HEAD reuse. Pass --reasoning-effort to override adaptive reasoning.
Skills
Hodor discovers repository-specific review guidelines from .agents/skills/, the cross-client Agent Skills convention:
mkdir -p .agents/skills/review-guidelines
# .agents/skills/review-guidelines/SKILL.md
---
name: review-guidelines
description: Security and performance review checklist.
---
- All API endpoints must have authentication checks.
- Database queries must use parameterized statements.
- API responses should be < 200ms p95.
Skills are loaded automatically during reviews. See SKILLS.md for details.
Development
bun install # Install dependencies
bun run build # Build
bun run test # Run tests
bun run eval:list # Validate and list review-quality eval cases
bun run eval -- --model <provider/model> # Execute model evals (uses API credentials)
bun run dev -- <url> # Run from source
Architecture
Hodor is written in TypeScript and runs on Bun. Key components:
| Module | Purpose |
|---|---|
src/cli.ts |
Commander.js CLI entry point |
src/agent.ts |
Core review orchestration, URL parsing, comment posting |
src/workspace.ts |
CI detection, repo cloning, branch checkout |
src/prompt.ts |
Dynamic review task construction from PR or local-diff context |
src/review-instructions.ts |
Default review profile loading and custom profile validation |
src/system-prompt.ts |
Review profile, additional instructions, and Hodor review protocol composition |
src/model.ts |
Model string parsing, API key resolution |
src/gitlab.ts |
GitLab API via glab CLI (comments, inline notes, draft notes, commit status) |
src/github.ts |
GitHub API via gh CLI |
src/render.ts |
JSON review output → markdown rendering |
src/codequality.ts |
CodeClimate JSON artifact for GitLab code quality widget |
src/metrics.ts |
Token usage and cost formatting |
templates/ |
Bundled default review profile and dynamic review task template |
Hodor gives its read-only review agent the selected review profile, optional additional instructions, Hodor's review protocol, and a task built from the PR or local diff. The agent then analyzes the changed code and reports structured findings.
Learn More
Hodor Documentation
- SKILLS.md - Creating repository-specific review guidelines
- AUTOMATED_REVIEWS.md - Advanced CI/CD workflows
Contributing
Found a bug? Want to add a feature? Open an issue at https://github.com/mr-karan/hodor/issues.
License
MIT