Steep — Let your code steep

AI code review · built for Gitea

Code reviews with the full picture.

Steep explores pull requests inside an isolated Dev Container, then leaves focused, line-by-line feedback right where your team works.

Thoughtful by design

Useful reviews. No noisy pipeline.

Bring an AI reviewer into your Gitea workflow with a single comment.

Reviews on demand

Mention Steep in a pull-request comment and get an AI review streamed back to the PR. No CI hook to wire, no pipeline to learn.

Sandboxed by design

Every review runs in an ephemeral Dev Container with read-only tools. The network is cut after setup, and the container is removed when the review ends.

Lightweight & observable

A lean Rust service designed for fast reviews, with Prometheus metrics and Sentry error tracking.

From comment to context

Your code stays in its environment.

Steep gives the model tools to inspect the repository instead of sending the source code in the prompt.

Set up Steep
01

Steep hears your request

A Gitea pull-request comment triggers a review when you mention the bot.

02

A disposable workspace spins up

Steep clones the pull-request head and starts the repository's Dev Container—or a safe default when none is configured.

03

The model explores, read-only

It can inspect files with tools such as ls, read_file, and grep. Setup hooks run first; then network access is removed.

04

Feedback lands on the changed lines

Steep posts actionable findings with severity labels, plus a concise summary of what the PR does well.

What’s brewing

The roadmap

From safer reviews to an assistant that can help move work forward.

  • 1.2Sandboxed pull-request reviews.
  • 1.2.1A default Dev Container when a repository has no configuration.
  • 1.3Durable reviews: persist jobs in PostgreSQL, list them by state (running, pending, review done), and stream live updates over SSE.
  • 1.4Configuration from a YAML file, replacing part of the environment variables.
  • 2.0Type-safe action routing between reviews and implementation requests, implement requested changes from issues or existing PRs, then create or update a PR automatically.
  • 2.1Project instructions from AGENTS.md and separate review/implementation models.
  • 2.2Sub-agents that take on well-scoped parts of a task and run in parallel.
  • 3.0Automatically investigate and fix project errors reported by Sentry.

A few minutes to get steeping

Bring Steep to your Gitea.

Follow these steps in order. You will need a Rust toolchain, a reachable Docker or Podman daemon, an OpenRouter API key, and a Gitea account for Steep.

1. Install and configure

  1. Clone the source
    git clone https://gitea.qpismont.fr/qpismont/herald.git
    cd herald
  2. Create a Gitea token

    Create a token for the account Steep should act as. Give it access to the repositories it will review, including permission to read pull requests and publish comments/reviews. Steep uses this token to identify the account; you will use that account's username when asking for a review.

  3. Configure every required setting
    cp .env.example .env
    $EDITOR .env

    Set all nine required variables:

    • GITEA_URL — base URL, e.g. https://gitea.example.com (no /api/v1)
    • GITEA_TOKEN — the token created above
    • GITEA_TIMEOUT — API timeout in seconds
    • OPEN_ROUTER_API_KEY — your OpenRouter key
    • OPEN_ROUTER_MODEL — an available OpenRouter model ID
    • OPEN_ROUTER_TIMEOUT — request timeout in seconds
    • BOT_MAX_CONCURRENT — maximum simultaneous reviews
    • HTTP_PORT — web server port; use 3001 for the commands below
    • WEBHOOK_SIG_HEADER_SECRET — generate this in the next step

    Keep the example's numeric values for the timeouts and concurrency, or replace them with positive integers. Do not commit your completed .env.

  4. Generate and configure the webhook secret
    openssl rand -hex 32

    Copy the output into WEBHOOK_SIG_HEADER_SECRET in .env. You will enter the exact same value in Gitea in the next step.

  5. Start the daemon, build, and launch Steep
    podman system service --time=0 &
    export DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock
    cargo build --release -p steep-server
    ./target/release/steep-server

    Keep this process running. With Docker, omit the Podman command and use its socket; the default is unix:///var/run/docker.sock. Optional settings such as metrics and Sentry can be added later.

Explore the source on Gitea

2. Add the Gitea webhook

  1. Choose an address Gitea can reach

    In the repository's Settings → Webhooks, add a Gitea webhook. Set the target to Steep's public/reachable address and port:

    http://steep.example.com:3001/webhook
    Replace the host and scheme with yours. Do not use localhost unless Gitea and Steep share that network.
  2. Select the event and set the secret

    Enable at least Pull Request Comment. Paste the generated value into Gitea's Secret field; it must exactly match WEBHOOK_SIG_HEADER_SECRET.

  3. Allow the connection

    Make sure Gitea can connect to Steep on port 3001 (or your configured HTTP_PORT), including through any firewall or reverse proxy. Steep must also be able to reach Gitea's API, OpenRouter, and the container daemon.

  4. Trigger a review

    Open a pull request and add a comment that starts with @username, using the username of the Gitea account behind GITEA_TOKEN. For example:

    @steep review this PR

    The mention must be at the very start of the comment. If nothing happens, check the webhook's delivery history in Gitea and Steep's logs.