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

Repository files navigation

hoverstare logo

HoverStare

AI code review that actually reads your repo.

The name comes from the Stephen Chow movie gag "凌空瞪" — a disembodied eyeball floating in mid-air, staring you down.

CI release crates.io license 1PL

English · 简体中文 · Русский · Français · Deutsch · Español


HoverStare is an AI code review bot for GitHub pull requests, written in Rust and shipped as a single static binary that runs as a GitHub Action. Instead of tossing a diff at a model in one shot, its reviewer reads your repository like a human reviewer would — opening context files, grepping call sites, comparing against the base branch — before it says anything. A multi-pass vote plus an independent verifier keeps false positives down, and every finding it reports is tracked across commits until it's fixed.

Why HoverStare?

  • 🔍 Repo-aware, not diff-only. The reviewing model gets a read-only tool set (read_file / grep / glob / show_base_file) and uses it to verify suspicions before reporting. It catches bugs that hide outside the diff — like a changed function whose callers break two files away.
  • 🗳️ Multi-pass voting + verifier. Three independent review passes (correctness / concurrency / security lenses) vote on findings; lone-vote findings must survive an independent verifier pass with tool access. High signal, low noise.
  • 📌 Precise inline comments. Line numbers are validated against the real diff and snapped to the nearest valid anchor, so comments land exactly where the bug is — never on the wrong line.
  • 🔁 Incremental reviews. Push a fix and HoverStare reviews only the delta, marks fixed findings as resolved (or leaves a "✅ confirmed fixed" note), and never repeats itself.
  • 🛡️ Fail-open by design. Network trouble, rate limits, or a flaky model will never block your CI.
  • 🔑 BYOK. Bring your own key: Anthropic, or any OpenAI-compatible endpoint (Kimi, DeepSeek, OpenRouter, …). Code goes straight to your provider.

How it works

flowchart LR
    A[PR opened / synchronized] --> B{skip?}
    B -->|draft / bot / empty diff| Z((exit 0))
    B --> C[fetch diff]
    C --> D{prior review?}
    D -->|yes| E[delta diff]
    D -->|no| F[full diff]
    E --> G
    F --> G["N parallel review passes<br/>(read-only repo tools)"]
    G --> H[cluster & vote]
    H --> I[verifier pass]
    I --> J[validate & anchor lines]
    J --> K["post review<br/>+ resolve fixed threads<br/>+ status checks"]
Loading

Every inline comment carries a hidden fingerprint (path + code line + title hash). On the next push, HoverStare diffs against its previous review, asks the model which open findings are fixed, and resolves those threads — immune to line-number drift.

Quick start (2 minutes)

1. Add the workflow.github/workflows/hoverstare.yml:

name: HoverStare
on:
  pull_request:
    types: [opened, reopened, synchronize]
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]

permissions:
  contents: read
  pull-requests: write
  statuses: write

concurrency:
  # 不含 @hoverstare 的评论事件给独立组名,避免无意义的 run 取消正在跑的审查
  group: >-
    hoverstare-${{
      (github.event_name == 'issue_comment' || github.event_name == 'pull_request_review_comment')
      && !contains(github.event.comment.body, '@hoverstare')
      && format('noop-{0}', github.event.comment.id)
      || (github.event.pull_request.number || github.event.issue.number)
    }}
  cancel-in-progress: true

jobs:
  hoverstare:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: liuchong/hoverstare@v0.0.5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          OPENAI_API_KEY: ${{ secrets.HOVERSTARE_LLM_KEY }}
          OPENAI_BASE_URL: ${{ vars.HOVERSTARE_LLM_BASE_URL }}
          HOVERSTARE_MODEL: ${{ vars.HOVERSTARE_MODEL }}   # e.g. kimi-for-coding

2. Configure LLM credentials (pick one):

Provider Settings
Anthropic secret ANTHROPIC_API_KEY (default model claude-sonnet-4-6)
OpenAI-compatible (Kimi, DeepSeek, OpenRouter…) secret OPENAI_API_KEY, var OPENAI_BASE_URL (e.g. https://api.kimi.com/coding/v1), and a model name via var HOVERSTARE_MODEL or model in .github/hoverstare.toml

⚠️ With an OpenAI-compatible endpoint you must set the model name — the default claude-sonnet-4-6 won't exist there.

3. (Optional) Repo config.github/hoverstare.toml, every field optional:

model = "kimi-for-coding"             # main review model
reformat_model = "kimi-for-coding-highspeed"  # cheap model for output repair
passes = 3                            # parallel review passes; 1 disables voting
verify = true                         # verifier pass for single-vote findings
severity_threshold = "medium"         # below this → Nitpicks section only
ignore = ["*.lock", "**/dist/**", "**/*.min.js"]
max_diff_kb = 400                     # diff budget (truncated by priority)
max_tool_calls = 20                   # agentic loop tool budget
timeout_secs = 900
review_drafts = false
fail_closed = false                   # true → analysis failures fail CI
status_checks = false                 # write hoverstare / hoverstare-findings checks
language = "en"                       # output language: en/zh-CN/ru/fr/de/es
set_temperature = true                # false for endpoints that only accept default temperature
instructions = ""                     # team-specific review focus, injected into the system prompt

Repository instructions

HoverStare reads repo-level rule files and applies them to reviews (they supplement but never override the built-in core rules). Precedence:

  1. hoverstare.md / .hoverstare.md / .hoverstare/*.md / .github/hoverstare.md
  2. AGENTS.md
  3. .github/copilot-instructions.md, CLAUDE.md, .cursorrules

Files are read from the base branch (a PR editing AGENTS.md cannot inject instructions). Core safety rules (read-only tools, targeted verification, defect-only scope, JSON contract) can never be overridden.

Optional: brand identity (posts as your own bot)

By default, reviews post as github-actions[bot] — that's a GITHUB_TOKEN limitation, and it's the recommended mode for most users (zero extra setup).

Want a branded bot identity? Register your own GitHub App (5 minutes, no server needed — token exchange happens inside GitHub Actions) and pass its credentials to the action:

  1. Create a GitHub App at Settings → Developer settings → GitHub Apps (webhook off; permissions: contents read, pull-requests write, issues write, commit statuses write), install it on your repo
  2. Add its App ID and private key as secrets APP_ID / APP_PRIVATE_KEY
  3. Pass them:
      - uses: liuchong/hoverstare@v0.0.5
        with:
          app_id: ${{ secrets.APP_ID }}
          app_private_key: ${{ secrets.APP_PRIVATE_KEY }}

Reviews then post as your-app-name[bot], and resolveReviewThread works without the GITHUB_TOKEN limitation (no GH_PAT needed).

Zero-config hoverstare[bot] identity for everyone is on the roadmap as an optional self-hostable hoverstare serve webhook service.

@hoverstare commands

Post in a PR (repo collaborators only):

Command What it does
@hoverstare review Force a full re-review
@hoverstare explain Reply in the thread with a plain-language explanation of the finding
@hoverstare help Command list

Develop mode: issues & PRs as your AI IDE

HoverStare can also develop — issues and PRs become a conversation-driven development environment (spec 11/12). Not automation glue that reacts to events: a place where you actually build the feature, end to end, in the open.

How a feature flows

Issue mainline — file an issue mentioning @hoverstare:

  1. It investigates the repo and replies with an analysis + plan (in comments).
  2. Discuss by simply replying; each round is answered in the thread.
  3. @hoverstare go — it creates a branch, implements, pushes, and opens a PR (with Closes #N).

PR mainline — on any same-repo PR:

  • @hoverstare <instruction> — it checks out the PR branch, develops, commits (Conventional Commits, authored as hoverstare[bot]), pushes back to the branch, and reports in a comment. Rounds that exhaust their budget self-continue (max 10 rounds per PR).
  • Humans can adjust by committing to the branch directly — the next round always syncs to the remote head first and never overwrites your commits.
  • @hoverstare merge — once checks are green and there are no conflicts, it squash-merges and deletes the source branch.

Setup

  1. Workflow: add the issues and pull_request_review triggers and grant contents: write + issues: write. .github/workflows/hoverstare.yml in this repo is a complete working example.
  2. Tokens (two duties, two tokens):
    • Identity (comments, reviews, opening PRs): the default GITHUB_TOKEN, or a GitHub App token for the hoverstare[bot] identity.
    • Write operations (git push, merge, branch deletion): a PAT via the gh_pat input, or an App with contents: write. Pushes made with the default GITHUB_TOKEN do not trigger CI, so required checks would never run on bot commits.
  3. Permissions (optional): declare who can use what in .github/hoverstare.toml — see spec 12. Defaults: auto-review for anyone, @review/develop for collaborators, merge for users with write access.

Notes

  • Only repo collaborators can issue commands; fork PRs are out of scope.
  • PRs opened by the bot may hold CI in action_required state until approved, depending on your repo's Actions approval policy (first-time contributors).
  • Large tasks are sliced into budgeted rounds; the bot self-continues (max 10 rounds per PR). It cannot run builds or tests — CI failures are relayed back as instructions for the next round.

FAQ

Reviews/comments fail with permission errors? Check workflow permissions (pull-requests: write required) and repo Settings → Actions → General → Workflow permissions is "Read and write".

"model not found"? You configured an OpenAI-compatible endpoint but no model name. Set HOVERSTARE_MODEL (or model in hoverstare.toml).

400 / invalid temperature? Your endpoint only accepts the default temperature. Set set_temperature = false in hoverstare.toml.

Fixed findings aren't getting resolved? A GitHub platform limitation: the default GITHUB_TOKEN cannot call resolveReviewThread. HoverStare falls back to a "✅ confirmed fixed" reply in the thread. For full resolution, store a classic PAT (repo scope) as secret GH_PAT and pass it in the workflow env.

GitHub Enterprise? Set GITHUB_API_URL=https://<your-ghe-host>/api/v3.

@hoverstare merge fails with 403? The merge endpoint needs contents: write. Pass a PAT via gh_pat, or grant the GitHub App Contents: Read and write (and accept the upgrade on the installation).

CI on the bot's PR sits at action_required? That's GitHub's approval policy for outside/first-time contributors. Approve the runs once, or relax it under Settings → Actions → General → Fork pull request workflows.

A go/dev round says "no changes, no PR created"? Usually the task was too vague for one budgeted round. Reply with a sharper, smaller instruction (files to touch, acceptance criteria) and run go again — see the bot's comment for what it actually did.

Local development

# Dry-run a full review of a public PR (no publishing)
export OPENAI_API_KEY=... OPENAI_BASE_URL=... HOVERSTARE_MODEL=...
cargo run -- review --repo owner/repo --pr 123 --dry-run

# Review a local diff file (prints tool-call trace)
cargo run --example local_review -- path/to.diff [base_ref]

cargo test                                   # unit + httpmock contract tests
cargo clippy --all-targets -- -D warnings
cargo fmt

Specs and the milestone plan live in specs/ — the single source of truth for design decisions.

Contributing

See CONTRIBUTING.md for the quality gate, commit-message convention, and PR review process.

Star history & contributors

Auto-updated daily by RepoScope — committed to the orphan reposcope branch, never to master.

Star History

Contributors

License

1PL — One Public License

About

Code is cheap, help out with your tokens!

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages