# Technical Orientation

> What AsyncReview is, how its Python packages, CLI commands, RLM review loop, and web review surface fit together, and how the rest of this developer reference is organized.

- Repository: AsyncFuncAI/AsyncReview
- GitHub: https://github.com/AsyncFuncAI/AsyncReview
- Human wiki: https://grok-wiki.com/public/wiki/asyncfuncai-asyncreview-fb80a82d8c3a
- Complete Markdown: https://grok-wiki.com/public/wiki/asyncfuncai-asyncreview-fb80a82d8c3a/llms-full.txt

## Source Files

- `README.md`
- `pyproject.toml`
- `INSTALLATION.md`
- `cr/cli.py`
- `cli/main.py`
- `web/src/App.tsx`

---

<details>
<summary>Relevant source files</summary>
The following files were used as context for generating this wiki page:
- [README.md](README.md)
- [INSTALLATION.md](INSTALLATION.md)
- [pyproject.toml](pyproject.toml)
- [cr/cli.py](cr/cli.py)
- [cli/main.py](cli/main.py)
- [cr/rlm_runner.py](cr/rlm_runner.py)
- [cr/diff_rlm.py](cr/diff_rlm.py)
- [cr/server.py](cr/server.py)
- [cr/github.py](cr/github.py)
- [cr/config.py](cr/config.py)
- [cr/snapshot.py](cr/snapshot.py)
- [web/src/App.tsx](web/src/App.tsx)
- [web/src/components/ChatPanel.tsx](web/src/components/ChatPanel.tsx)
- [web/vite.config.ts](web/vite.config.ts)
- [npx/src/index.ts](npx/src/index.ts)
- [npx/src/launcher.ts](npx/src/launcher.ts)
- [skills/asyncreview/SKILL.md](skills/asyncreview/SKILL.md)
</details>

# Technical Orientation

AsyncReview is a code-review system for GitHub pull requests, GitHub issues, and local repositories. Its core idea is to give a language-model review loop executable context: the model can reason, generate Python, run that code through DSPy’s RLM interpreter, inspect repository or diff data, and return answers with cited sources.

This page explains how the Python packages, command-line entry points, recursive review loop, GitHub ingestion layer, and React web surface fit together. It also orients the rest of the developer reference: start here for boundaries and data flow, then move into focused pages for the CLI, RLM runtime, GitHub loading, web UI, configuration, and tests.

Sources: [README.md:3-6](), [README.md:38-48](), [pyproject.toml:1-22](), [pyproject.toml:32-42]()

## Product Workflows

AsyncReview exposes three main developer workflows:

| Workflow | User entry point | Backend path | Primary responsibility |
|---|---|---|---|
| Zero-install GitHub review | `npx asyncreview review --url ... -q ...` | Node launcher plus packaged Python runtime | Review a GitHub PR or issue from a URL without cloning the repository. |
| Local repository Q&A | `cr ask` or `cr review -q ...` | `cr.cli` and `CodebaseReviewRLM` | Snapshot a local repo and run an RLM question-answer loop over the codebase. |
| Web PR review | `cr serve` plus `web` dev server | FastAPI API, GitHub loader, diff RLMs, React UI | Load a PR, render changed files, run automatic review, and support chat over diffs. |

The README positions `npx asyncreview` as the default path for PR and issue review, while the installation guide describes the full local API server and web UI setup. The Python package publishes both `cr` and `asyncreview` console scripts, so the repository intentionally contains both local-codebase and GitHub-URL review surfaces.

Sources: [README.md:49-62](), [README.md:63-99](), [INSTALLATION.md:106-153](), [pyproject.toml:32-34]()

## High-Level Architecture

```mermaid
flowchart LR
  subgraph CLI["Command-line surfaces"]
    CR["cr: local ask/review/serve"]
    ASYNC["asyncreview: GitHub URL review"]
    NPX["npx wrapper"]
  end

  subgraph Python["Python review runtime"]
    SNAP["cr.snapshot"]
    RLM["cr.rlm_runner.CodebaseReviewRLM"]
    DIFF["cr.diff_rlm DiffQARLM / FastAutoReview"]
    GH["cr.github / cli.github_fetcher"]
    API["cr.server FastAPI"]
  end

  subgraph Web["Web review surface"]
    APP["web/src/App.tsx"]
    CHAT["ChatPanel SSE chat"]
    DIFFVIEW["DiffViewer / PR panels"]
  end

  subgraph External["External systems"]
    GITHUB["GitHub API"]
    DSPY["DSPy RLM + PythonInterpreter"]
    DENO["Deno/Pyodide execution"]
  end

  NPX --> ASYNC
  CR --> SNAP
  CR --> RLM
  CR --> API
  ASYNC --> GH
  ASYNC --> RLM
  API --> GH
  API --> DIFF
  APP --> API
  CHAT --> API
  GH --> GITHUB
  RLM --> DSPY
  DIFF --> DSPY
  DSPY --> DENO
```

The important boundary is that the web app does not call GitHub or the model directly. It calls local API endpoints under `/api`, which are proxied by Vite to the FastAPI server. The FastAPI server owns PR loading, cached review IDs, diff question-answering, automatic review, and streaming events. The CLI paths bypass the React UI and run either local snapshots or virtual GitHub contexts directly.

Sources: [cr/cli.py:136-178](), [cli/main.py:109-178](), [cr/server.py:109-187](), [web/vite.config.ts:4-14](), [web/src/App.tsx:107-164]()

## Python Packages and Entry Points

The root Python project is named `cr` and builds two packages: `cr` and `cli`. Its dependencies include DSPy, Rich, dotenv, HTTPX, FastAPI, Uvicorn, and SSE support. The two published console scripts are:

| Script | Target | Role |
|---|---|---|
| `cr` | `cr.cli:main` | Local repository review, interactive ask mode, and API server startup. |
| `asyncreview` | `cli.main:main` | GitHub PR/issue URL review for packaged or NPX usage. |

`cr.cli` defines `review`, `ask`, and `serve`. `review` builds a local snapshot and runs a one-shot question. `ask` builds the same snapshot, keeps conversation history in memory, and supports local commands such as `history`, `files`, and `info`. `serve` imports `cr.server:app` and starts Uvicorn using configured host and port.

Sources: [pyproject.toml:13-22](), [pyproject.toml:32-42](), [cr/cli.py:25-103](), [cr/cli.py:105-134](), [cr/cli.py:136-178]()

### GitHub URL CLI

The `asyncreview` Python CLI is focused on URL-based review. It validates a GitHub URL, creates a `VirtualReviewRunner`, runs the review asynchronously, and formats the result as text, Markdown, or JSON. It accepts an optional model override and quiet mode for scripting.

Sources: [cli/main.py:53-107](), [cli/main.py:130-175]()

The NPX package adds a Node command wrapper. The TypeScript CLI validates that exactly one of `--url` or `--path` is supplied, while the runtime launcher detects OS/architecture, downloads a release tarball into a user cache if needed, and spawns the cached runtime with inherited stdio and environment.

Sources: [npx/src/index.ts:12-42](), [npx/src/launcher.ts:31-87](), [npx/src/launcher.ts:138-206]()

## Local Codebase Review Loop

Local review starts by converting a repository directory into a `CodebaseSnapshot`. Snapshotting walks the tree, filters default ignored directories and file types, honors include/exclude globs, prioritizes important manifests and source/test directories, skips oversized or binary files, decodes UTF-8 content, detects language, extracts simple symbols, and records repository metadata.

Sources: [cr/config.py:16-24](), [cr/config.py:35-139](), [cr/snapshot.py:229-253](), [cr/snapshot.py:260-323]()

`CodebaseReviewRLM` then configures DSPy with the main model, creates a `PythonInterpreter` backed by a Deno command, and constructs a DSPy `RLM` with the signature `codebase, conversation_history, question -> answer, sources`. Each run builds a fresh snapshot, formats conversation history, invokes the RLM, normalizes returned sources, captures trace steps from DSPy logging, and optionally saves traces under the configured traces directory.

Sources: [cr/rlm_runner.py:26-70](), [cr/rlm_runner.py:73-161](), [cr/rlm_runner.py:187-220](), [cr/rlm_runner.py:222-306]()

```python
# cr/rlm_runner.py
self._rlm = dspy.RLM(
    signature="codebase, conversation_history, question -> answer, sources",
    max_iterations=MAX_ITERATIONS,
    max_llm_calls=MAX_LLM_CALLS,
    sub_lm=dspy.LM(SUB_MODEL),
    verbose=True,
    interpreter=interpreter,
)
```

Sources: [cr/rlm_runner.py:212-219]()

## GitHub PR and Issue Review

The web backend and URL CLI both depend on GitHub API data, but they use different adapters.

The web path uses `cr.github`. It parses PR URLs, fetches PR metadata, changed files, commits, and issue comments, converts changed files into dictionaries containing path, status, additions, deletions, and patch, then stores the resulting `PRInfo` in an in-memory cache keyed by an eight-character review ID. File contents are fetched later from the GitHub contents API at both base and head SHAs.

Sources: [cr/github.py:20-47](), [cr/github.py:50-80](), [cr/github.py:82-169](), [cr/github.py:172-235]()

The URL CLI path uses `VirtualReviewRunner`. It parses the URL, fetches either PR or issue data through `cli.github_fetcher`, builds a text review context, configures DSPy RLM, runs the synchronous RLM in an executor, and returns answer, sources, and metadata.

Sources: [cli/virtual_runner.py:19-83](), [cli/virtual_runner.py:85-140]()

## Diff Review RLMs

The web review loop has two distinct model paths in `cr.diff_rlm`:

| Class | Trigger | Model style | Output |
|---|---|---|---|
| `DiffQARLM` | User asks a question in chat | DSPy RLM with executable Python iterations | Markdown/code answer blocks plus diff citations. |
| `FastAutoReview` | PR is loaded in the web app | DSPy `ChainOfThought` predictor | Issues grouped into bug, investigation, or informational categories plus a summary. |

`DiffQARLM` builds diff context from file contents, formats conversation and selected line ranges, and calls an RLM signature of `diff_context, pr_info, selection, conversation, question -> answer, citations`. Its streaming variant fetches up to 50 files in parallel, injects `file_data` into the REPL variables, manually advances RLM iterations, yields `RLMIteration` objects for the UI, and finally yields parsed answer blocks and citations.

Sources: [cr/diff_rlm.py:1-6](), [cr/diff_rlm.py:181-208](), [cr/diff_rlm.py:210-278](), [cr/diff_rlm.py:280-442]()

`FastAutoReview` is intentionally simpler. It uses PR patches for up to 100 files, adds instructions requiring diff-bounded citations, runs a synchronous DSPy predictor in a worker thread, parses JSON-like issue output, and converts issue dictionaries into typed `ReviewIssue` objects.

Sources: [cr/diff_rlm.py:446-574]()

## FastAPI Review API

`cr.server` is the integration layer for the web app. It creates a FastAPI app, enables permissive CORS for local development, lazily initializes shared `DiffQARLM` and `FastAutoReview` instances, and exposes endpoints for PR loading, file content retrieval, diff chat, automatic review, suggestions, streaming chat, health checks, and SSE testing.

| Endpoint | Purpose |
|---|---|
| `POST /api/github/load_pr` | Load PR metadata and changed files, returning a `reviewId`. |
| `GET /api/github/file` | Fetch base/head contents for one PR file. |
| `POST /api/diff/ask` | Non-streaming diff Q&A. |
| `POST /api/diff/review` | Automatic bug/risk review. |
| `POST /api/diff/ask/stream` | SSE stream of RLM iterations and final answer blocks. |
| `POST /api/suggestions` | Generate follow-up suggestions with fallback defaults. |
| `GET /health` | Server health check. |

Sources: [cr/server.py:17-49](), [cr/server.py:51-107](), [cr/server.py:109-187](), [cr/server.py:190-217](), [cr/server.py:219-311](), [cr/server.py:314-343]()

The streaming endpoint emits structured SSE messages: `start`, repeated `iteration` events, answer `block` events, `citations`, and `complete`. This is the bridge that lets the UI show the recursive process rather than only the final answer.

Sources: [cr/server.py:219-284](), [cr/server.py:287-311]()

## Web Review Surface

The React app is organized around three panes: a file list and PR loader, a summary/diff pane, and a resizable right panel with chat, flags, and bugs. Loading a PR posts the entered URL to `/api/github/load_pr`, stores returned `PRInfo`, and selects the first changed file. When a `reviewId` appears, the app automatically posts to `/api/diff/review` and splits returned issues into bug and flag lists.

Sources: [web/src/App.tsx:11-24](), [web/src/App.tsx:107-164](), [web/src/App.tsx:178-180](), [web/src/App.tsx:182-246](), [web/src/App.tsx:274-393]()

`ChatPanel` owns the interactive review conversation. It offers quick actions, sends questions to `/api/diff/ask/stream`, includes the current diff selection when present, reads the response body as an SSE stream, appends RLM iterations to the assistant message, renders final Markdown/code blocks, and requests follow-up suggestions after assistant responses.

Sources: [web/src/components/ChatPanel.tsx:16-21](), [web/src/components/ChatPanel.tsx:72-167](), [web/src/components/ChatPanel.tsx:189-328](), [web/src/components/ChatPanel.tsx:330-361](), [web/src/components/ChatPanel.tsx:370-490]()

## Configuration and Portability

The current implementation defaults to Gemini model identifiers through DSPy: `MAIN_MODEL` defaults to `gemini/gemini-3-pro-preview`, and `SUB_MODEL` defaults to `gemini/gemini-3-flash-preview`. It also reads `GEMINI_API_KEY`, `GITHUB_TOKEN`, snapshot size limits, cache paths, GitHub API base URL, and API host/port from environment variables. The architecture should be read as BYOK-friendly because keys are injected from the environment, but the checked-in code is not provider-neutral at the model-adapter level unless those model strings and DSPy configuration are changed.

Sources: [cr/config.py:1-33](), [cr/rlm_runner.py:200-220](), [cli/virtual_runner.py:61-83]()

The repository also includes an `asyncreview` skill definition for agent integrations. That file describes AsyncReview as a portable skill invoked through `npx asyncreview`, with prerequisites around `GEMINI_API_KEY` and optional `GITHUB_TOKEN`. Treat this as workflow documentation for compatible agents, not as a separate runtime dependency for the Python or web implementation.

Sources: [skills/asyncreview/SKILL.md:1-5](), [skills/asyncreview/SKILL.md:19-28](), [skills/asyncreview/SKILL.md:174-179]()

## How This Developer Reference Is Organized

Use this page as the map. The rest of the reference should stay source-backed and split by implementation responsibility:

| Reference page | What it should cover | Main source owners |
|---|---|---|
| CLI Commands | `cr`, `asyncreview`, NPX launcher, output formats, local vs URL review. | `cr/cli.py`, `cli/main.py`, `cli/virtual_runner.py`, `npx/src/*` |
| RLM Runtime | DSPy setup, Deno interpreter command, trace capture, local snapshots, iteration limits. | `cr/rlm_runner.py`, `cr/snapshot.py`, `cr/config.py` |
| GitHub Ingestion | PR URL parsing, API calls, review ID cache, file content loading. | `cr/github.py`, `cli/github_fetcher.py` |
| Web API | FastAPI request/response models, endpoints, SSE event contract. | `cr/server.py`, `cr/diff_rlm.py` |
| Web UI | PR loading, diff viewing, chat streaming, flags and bugs panels. | `web/src/App.tsx`, `web/src/components/*`, `web/src/types.ts` |
| Configuration and Setup | Environment variables, local server ports, frontend proxy, install prerequisites. | `INSTALLATION.md`, `cr/config.py`, `web/vite.config.ts`, `pyproject.toml` |

Sources: [INSTALLATION.md:13-19](), [INSTALLATION.md:61-79](), [INSTALLATION.md:106-153](), [INSTALLATION.md:195-225](), [web/package.json:5-30]()

## Closing Summary

AsyncReview is best understood as a set of review surfaces over one core pattern: collect code or diff context, run a DSPy-backed review loop or predictor, and present cited findings through CLI output or a web UI. The local `cr` command focuses on repository snapshots, `asyncreview` focuses on GitHub URLs, and the web app coordinates PR loading, automated issue discovery, and streaming diff chat through FastAPI.

Sources: [cr/cli.py:25-38](), [cli/main.py:53-83](), [cr/server.py:140-187](), [web/src/App.tsx:139-180]()
