@zawlinnnaing/ai-review-cli
v1.2.0
Published
AI-powered code review CLI for GitLab Merge Requests
Readme
ai-review CLI
A local developer tool that enables AI agents (Claude Code, Cursor, GitHub Copilot, etc.) to perform automated Merge Request code reviews against GitLab.
Installation
Option A — Download pre-built binary from GitHub release (recommended)
Pre-built binaries are published to the GitHub releases page for every version tag. No Node.js required.
Download the appropriate binary for your platform using curl or Invoke-WebRequest in PowerShell, make it executable, and move it to a directory on your PATH.
NOTE: If you already downloaded a release binary from the GitHub releases page, you don't need to run the download command. Just make it executable and move it to your PATH. The binary must be named
ai-review(orai-review.exeon Windows) to work correctly with the bundled SKILL.md agent skill.
macOS (Intel and Apple Silicon)
Apple Silicon users should use the x64 binary via Rosetta 2.
curl -L "https://github.com/zawlinnnaing/ai-review-cli/releases/download/v<VERSION>/ai-review-macos-x64" \
-o ai-review
chmod +x ai-review
sudo mv ai-review /usr/local/bin/Linux (x64)
curl -L "https://github.com/zawlinnnaing/ai-review-cli/releases/download/v<VERSION>/ai-review-linux-x64" \
-o ai-review
chmod +x ai-review
sudo mv ai-review /usr/local/bin/Linux (ARM64)
curl -L "https://github.com/zawlinnnaing/ai-review-cli/releases/download/v<VERSION>/ai-review-linux-arm64" \
-o ai-review
chmod +x ai-review
sudo mv ai-review /usr/local/bin/Windows (x64)
Invoke-WebRequest -Uri "https://github.com/zawlinnnaing/ai-review-cli/releases/download/v<VERSION>/ai-review-win-x64.exe" `
-OutFile "ai-review.exe"
# Move ai-review.exe to a directory on your PATHReplace <VERSION> with the desired release version (e.g. 1.2.3). Available releases are listed on the releases page.
Option B — Install from npm registry
The package is published to the public npm registry:
npm install -g @zawlinnnaing/ai-review-cliAgent skill
Note: CLI must be installed via Option A or B for the skill to work correctly with the expected command name
ai-review.
This repository ships reusable AI agent skills under the skills/ directory:
| Skill | Description |
|-------|-------------|
| skills/mr-review | Review a GitLab MR: fetch context, analyse, validate, and optionally post inline comments |
Install a skill globally or into your current project with:
# MR review skill
npx skills add https://github.com/zawlinnnaing/ai-review-cli/skills/mr-reviewOnce installed, your agent can invoke the skill to check credentials, fetch MR context, generate a structured review, validate it, and optionally post comments — all in one step.
Usage
This tool acts as a bridge between your AI IDE and Git Provider (GitLab). The agent calls ai-review to fetch structured MR context, performs its own code review, and validates the output against a schema before posting comments back.
Step 1 — Configure credentials (one-time)
Run this once for every GitLab instance you work with:
ai-review configure gitlabYou will be prompted for your GitLab base URL and a Personal Access Token with api and read_repository scopes.
Step 2 — Fetch MR context
ai-review get-context "<MR_URL>"Fetches the MR title, description, and all changed files with annotated diffs. Writes context to ~/.ai-review/mr-context.json by default.
Step 3 — Review with your AI agent
Claude Code users can run the entire review pipeline (Steps 2–5) in one go using the bundled slash command:
/review-mr <MR_URL>The /review-mr command fetches context, analyses the diff, validates the output, and optionally posts comments — all automatically.
For other AI agents (Cursor, GitHub Copilot, etc.), open the agent chat (Cmd+I in Cursor) and ask it to review the context file:
Review the MR context in ~/.ai-review/mr-context.json and return a structured review JSON with this format:
{
"comments": [
{
"file": "<file path>",
"line": <line number>,
"severity": "critical" | "warning" | "suggestion",
"comment": "<review comment>"
}
]
}
Save the result to review.json.Step 4 — Validate the review output
ai-review validate-output review.jsonValidates the agent's output against the review schema before posting. Exits with code 1 and a structured error if the output is malformed.
Step 5 — Post comments to the MR
ai-review post-comments "<MR_URL>" --input review.json
# Post only warnings and criticals
ai-review post-comments "<MR_URL>" --input review.json --severity warningPosts each comment from the validated review JSON as an inline discussion on the GitLab MR.
Step 6 — Post MR description
# Post a description directly
ai-review post-description "<MR_URL>" --text "My description"
# Or read the description from a review JSON file
ai-review post-description "<MR_URL>" --input review-output.jsonUpdates the MR description on GitLab. Useful when your AI agent generates a structured summary as part of the review output.
How it works end-to-end
You (in IDE chat)
│ "Review MR #123"
▼
AI Agent
│ ai-review get-context <MR_URL> [--stdout | --output <path>]
▼
ai-review CLI ──► GitLab API
│ returns MRContext JSON
▼
AI Agent (runs code review → writes review.json)
│ ai-review validate-output review.json
▼
ai-review CLI (schema validation)
│ ai-review post-comments <MR_URL> --input review.json
▼
ai-review CLI ──► GitLab API (posts inline discussions)
│ success summary
▼
YouCommands
Check CLI version
ai-review --versionPrints the CLI version sourced from package.json so the flag stays in sync with releases.
Configure GitLab credentials
ai-review configure gitlabPrompts for your Personal Access Token and base URL, then stores the entry (keyed by domain) at ~/.ai-review/credentials.json.
Run the command once per GitLab instance you want to use.
Required GitLab token scopes: api, read_repository.
Example credentials file with multiple instances:
{
"gitlab": {
"gitlab.com": {
"token": "glpat-xxxxx",
"baseUrl": "https://gitlab.com"
},
"gitlab.mycompany.com": {
"token": "glpat-yyyyy",
"baseUrl": "https://gitlab.mycompany.com"
}
}
}Fetch MR context
ai-review get-context <MR_URL> [--stdout] [--output <path>]Pass the full GitLab Merge Request URL — works for both gitlab.com and self-hosted instances.
The correct credentials are selected automatically based on the URL's domain.
| Flag | Behaviour |
| ----------------------- | ------------------------------------------------------------------------- |
| (none) | Writes JSON to ~/.ai-review/mr-context.json and logs the path to stderr |
| --stdout | Prints JSON to stdout |
| --output <path> | Writes JSON to the specified path and logs it to stderr |
| --output + --stdout | --output takes precedence; writes to the specified path |
# Default — writes to ~/.ai-review/mr-context.json
ai-review get-context https://gitlab.com/group/repo/-/merge_requests/123
# Print to stdout
ai-review get-context https://gitlab.com/group/repo/-/merge_requests/123 --stdout
# Write to a custom path
ai-review get-context https://gitlab.com/group/repo/-/merge_requests/123 --output /tmp/mr-context.json
# Self-hosted instance
ai-review get-context https://gitlab.mycompany.com/group/repo/-/merge_requests/456The JSON output has the following shape:
{
"title": "...",
"description": "...",
"sourceBranch": "...",
"targetBranch": "...",
"files": [
{
"path": "src/foo.ts",
"language": "typescript",
"diff": "..."
}
]
}Validate review output
ai-review validate-output <file>Validates an AI-generated review JSON file against the structured review output schema before posting comments.
ai-review validate-output review.jsonExpected input schema:
{
"comments": [
{
"file": "src/foo.ts",
"line": 42,
"severity": "warning",
"comment": "This function has no error handling."
}
]
}| Field | Type | Description |
| ---------- | ----------------------------------------- | ------------------------------- |
| file | string | File path relative to repo root |
| line | number | Line number in the new file |
| severity | "critical" \| "warning" \| "suggestion" | Severity level of the comment |
| comment | string | The review comment text |
On success, prints a summary to stdout:
Valid review output: 5 commentsOn failure, prints a structured error to stderr and exits with code 1:
{
"error": "INVALID_SCHEMA",
"message": "comments.0.severity: Invalid enum value..."
}Post review comments
ai-review post-comments <MR_URL> --input <file> [--severity <level>]Reads and validates the review JSON, then posts each comment as an inline discussion thread on the GitLab MR. The MR URL is parsed to resolve the domain, project path, and MR IID; credentials are selected automatically based on the URL's domain.
ai-review post-comments https://gitlab.com/group/repo/-/merge_requests/123 --input review.json
# Post only warnings and criticals
ai-review post-comments https://gitlab.com/group/repo/-/merge_requests/123 --input review.json --severity warning
# Self-hosted instance
ai-review post-comments https://gitlab.mycompany.com/group/repo/-/merge_requests/456 --input review.json| Option | Description |
| -------------------- | --------------------------------------------------------------------------------------------- |
| --input <file> | Path to the review JSON file (required) |
| --severity <level> | Minimum severity to post: suggestion | warning | critical. Omit to post all comments. |
Severity filter — when --severity is set, only comments at or above the specified level are posted:
| --severity value | Comments posted |
| ------------------ | ----------------------------- |
| suggestion | suggestion, warning, critical |
| warning | warning, critical |
| critical | critical only |
On success, prints a summary to stdout:
Posted 5 comments to MR.
Posted 3 comments to MR. (2 skipped below --severity warning)On failure, prints a structured error to stderr and exits with code 1:
{ "error": "POST_FAILED", "message": "Request failed with status code 422" }Post MR description
ai-review post-description <MR_URL> [--text <string>] [--input <file>]Updates the description of a GitLab MR. Credentials are resolved automatically from the URL's domain.
# Post a description as a plain string
ai-review post-description https://gitlab.com/group/repo/-/merge_requests/123 --text "## Summary\nThis MR refactors the auth module."
# Read the description from a review JSON file (looks for a \"description\" key)
ai-review post-description https://gitlab.com/group/repo/-/merge_requests/123 --input review-output.json
# Default file when --input is omitted
ai-review post-description https://gitlab.com/group/repo/-/merge_requests/123| Option | Description |
| ---------------- | ---------------------------------------------------------------------------------------- |
| --text <string> | Description text to post directly |
| --input <file> | Path to a JSON file with a "description" key (defaults to review-output.json) |
On success, prints:
MR description updated successfully.On failure, prints a structured error to stderr and exits with code 1:
{ "error": "POST_FAILED", "message": "..." }Create MR
ai-review create-mr <REPO_URL> <SOURCE_BRANCH> <TARGET_BRANCH> [--title <string>]Creates a new Merge Request on GitLab. The repo URL is used to resolve the domain, project path, and credentials — if no credentials are configured for that hostname the command fails immediately with a structured error.
# Create an MR from feature-branch into main
ai-review create-mr https://gitlab.com/group/repo feature-branch main
# Provide a custom title
ai-review create-mr https://gitlab.com/group/repo feature-branch main --title "feat: add login flow"
# Self-hosted instance
ai-review create-mr https://gitlab.mycompany.com/group/repo feature-branch main| Argument / Option | Description |
| --------------------- | --------------------------------------------------------------------------- |
| <REPO_URL> | Full HTTPS URL of the repository (.git suffix optional) |
| <SOURCE_BRANCH> | Branch to merge from |
| <TARGET_BRANCH> | Branch to merge into |
| --title <string> | MR title (defaults to Merge <source> into <target>) |
On success, prints the new MR URL and its JSON representation:
Merge request created: https://gitlab.com/group/repo/-/merge_requests/42
{
"id": 1001,
"iid": 42,
"title": "Merge feature-branch into main",
...
}On failure, prints a structured error to stderr and exits with code 1:
{ "error": "CREATE_MR_FAILED", "message": "No GitLab credentials configured for domain \"gitlab.com\". Run: ai-review configure gitlab" }Local Development
Requirements
- Node.js 20+
Install dependencies
npm installRun in development mode
npm run dev -- <COMMAND> <ARGUMENTS>Roadmap
| Phase | Scope | Status | | ----- | ------------------------------------- | ----------- | | 1 | MR Context Fetch CLI | ✅ Complete | | 2 | Prompt + Structured Output Validation | ✅ Complete | | 3 | Comment Publisher | ✅ Complete | | 4 | MCP Server | Future |
