RepoPilot은 로컬 환경에서 실행되는 Rust CLI 도구로, 아래 대상을 멀티 에이전트로 코드 리뷰합니다.
- GitHub Pull Request
- GitLab Merge Request
사용자는 PR/MR URL 하나만 입력하면 되고, 플랫폼(GitHub/GitLab)은 자동으로 감지됩니다.
- URL만으로 실행:
repopilot "<PR_OR_MR_URL>" - GitHub/GitLab 자동 감지
- 멀티 프로바이더 리뷰 (Codex, Claude, Gemini)
- API 키 대신 로컬에 설치/로그인된 CLI 명령 실행
- API 기반 diff 조회 (로컬 checkout 불필요)
- claim/final 마커 기반 중복 실행 방지
- 에이전트별 개별 코멘트 작성 + 최종 요약 코멘트 작성
- 최종 요약 코멘트에 "에이전트 간 상호 의견" 포함
- 여러 config 파일 경로 병합/덮어쓰기 지원
- 현재 적용 config 확인 명령:
repopilot config
RepoPilot은 **Clean Architecture + DDD + Hexagonal Architecture(Ports & Adapters)**를 함께 적용합니다.
핵심 원칙:
domain은 가장 안쪽(inside core)이며 외부 기술을 모릅니다.application은 유스케이스와 포트(인터페이스)를 소유합니다.interface는 인바운드 어댑터(사용자 입력)입니다.infrastructure는 아웃바운드 어댑터(외부 API/CLI/파일)입니다.- 의존성 방향은 안쪽으로만 향합니다.
의존성 규칙:
- 허용:
interface -> application,application -> domain,infrastructure -> application(ports), domain - 금지:
application -> infrastructure/interface,domain -> application/infrastructure/interface
현재 코드 매핑:
src/domain- 엔티티/값 객체/도메인 정책
- 예: SHA 마커 정책, 교차 에이전트 프롬프트 정책, 사용량 집계 정책
src/application- 유스케이스 + 포트
- 예:
usecases/review_pr/*,ports.rs
src/interface- 인바운드 인터페이스 계층
- 현재는 CLI 인터페이스만 구현:
src/interface/cli/* - 예:
src/interface/cli/command.rs,src/interface/cli/repl.rs,src/interface/cli/composition.rs
src/infrastructure- 아웃바운드 어댑터 구현
- 예:
vcs/*,providers/*,config/*,render.rs,adapters/*
RepoPilot provider는 두 가지 실행 모드를 지원합니다.
- API 모드(권장): provider별
api_key또는api_key_env설정 (CLI 설치 불필요) - CLI 모드: 로컬 바이너리(
codex/claude/gemini) 설치 + 로그인(OAuth)
동작 우선순위: API key가 있으면 API 모드, 없으면 CLI 모드.
VCS 코멘트/노트 작성에는 host 토큰이 필요합니다.
- PAT(간단):
GITHUB_TOKEN/GITLAB_TOKEN환경변수 또는hosts.<host>.token설정 - OAuth(권장):
gh/glab설치 후 로그인repopilot auth github(GitHub:gh auth login)repopilot auth gitlab(GitLab:glab auth login)
gh/glab 설치 예시:
- macOS(Homebrew):
brew install gh glab - Windows(winget):
winget install --id GitHub.cli/winget install --id glab.glab - Linux: 배포판 패키지 매니저로 설치(또는 공식 릴리즈 바이너리)
API 키를 쓰지 않고 로컬 CLI를 사용하려면 provider CLI 설치와 로그인이 필요할 수 있습니다.
- Codex:
codex(install:npm install -g @openai/codex)- 로그인:
repopilot auth codex(내부적으로codex login)
- 로그인:
- Claude Code:
claude(install:npm install -g @anthropic-ai/claude-code)- 로그인:
repopilot auth claude(내부적으로claude auth login)
- 로그인:
- Gemini CLI:
gemini(install:npm install -g @google/gemini-cli)- 로그인:
repopilot auth gemini(CLI 실행 후 Login with Google)
- 로그인:
참고:
- Node.js가 없으면
npm설치 방식은 사용할 수 없습니다(대신 brew/winget 등 사용). - API 키 모드라면 provider CLI가 없어도 됩니다:
OPENAI_API_KEY,ANTHROPIC_API_KEY,GEMINI_API_KEY.
cargo build --release소스에서 바로 실행:
cargo run --bin repopilot -- "https://github.com/org/repo/pull/123" --dry-run빌드된 바이너리 실행:
./target/release/repopilot "https://github.com/org/repo/pull/123"러너가 없어도 로컬 머신에서 직접 배포할 수 있습니다.
scripts/ 아래 스크립트가 로컬 태그 푸시 -> 빌드 -> Package 업로드 -> Release 생성/업데이트까지 처리합니다.
GITLAB_TOKEN=<YOUR_TOKEN> \
scripts/publish-gitlab.sh \
--project-id <PROJECT_ID> \
--tag v0.1.0 \
--gitlab-url https://gitlab.your-company.com옵션:
- 태그 푸시를 건너뛰려면
--no-tag-push - Release 생성/업데이트를 건너뛰려면
--no-release
$env:GITLAB_TOKEN=\"<YOUR_TOKEN>\"
.\\scripts\\publish-gitlab.ps1 `
-ProjectId <PROJECT_ID> `
-Tag v0.1.0 `
-GitLabUrl https://gitlab.your-company.comWindows 배포 스크립트도 기본적으로 태그를 생성/푸시합니다.
- 태그 푸시를 건너뛰려면
-NoTagPush - Release 생성/업데이트를 건너뛰려면
-NoRelease
macOS/Linux:
scripts/install-gitlab.sh \
--project-id <PROJECT_ID> \
--tag v0.1.0 \
--gitlab-url https://gitlab.your-company.com \
--token <YOUR_TOKEN>Windows:
.\\scripts\\install-gitlab.ps1 `
-ProjectId <PROJECT_ID> `
-Tag v0.1.0 `
-GitLabUrl https://gitlab.your-company.com `
-Token <YOUR_TOKEN>설치 후 어느 경로에서든 아래처럼 실행됩니다.
repopilot --help기본 명령:
repopilot "<PR_OR_MR_URL>"대화형 모드(슬래시 커맨드):
repopilot대화형 모드 시작 시 상태 대시보드가 먼저 출력됩니다.
- config 로딩 상태
- host/token 해석 상태
- provider별 실행 모드(api/cli)와 실행 가능 여부
- review guide 경로
- comment language
대화형 명령:
/로 입력을 시작하면 실시간 명령 추천 표시 (방향키 이동 + Tab 자동완성 + Enter 실행)/config/review <PR_OR_MR_URL> [--dry-run] [--force]/exit또는/quit
예시:
repopilot "https://github.com/org/repo/pull/123"
repopilot "https://gitlab.com/group/subgroup/repo/-/merge_requests/45"옵션:
--dry-run: 최종 Markdown만 stdout에 출력하고 코멘트/노트는 작성하지 않음--force: 현재 HEAD SHA에 대해 이미 claim/review가 있어도 강제로 재실행
최초 실행 시 설정 파일이 없으면 아래 템플릿이 자동 생성됩니다.
./.repopilot/config.json./.repopilot/review-guide.md
실행 흐름: 0. 상태 대시보드 출력
- claim 코멘트 생성/업데이트
- 각 에이전트 1차 리뷰 실행
- 에이전트별 개별 코멘트 생성/업데이트
- 각 에이전트가 다른 에이전트 의견에 대한 2차 코멘트 생성
- claim 코멘트를 최종 요약 코멘트로 업데이트
defaults.comment_language설정값으로 에이전트 응답 언어를 통일
상태 대시보드에는 아래가 포함됩니다.
- Config 정상 로딩 여부
- Target Host
- Host Token 해석 여부 및 API 접근 검증 결과
- Provider별 enabled/mode(api|cli)/실행 가능 여부
review_guide_path및 파일 존재 여부comment_language
RepoPilot은 아래 순서로 JSON config 파일을 읽고 병합합니다.
(낮은 우선순위 -> 높은 우선순위)
/etc/repopilot/config.json~/.config/repopilot/config.json(OS 표준 config 디렉터리)./.repopilot/config.json(recommended)REPOPILOT_CONFIG=/path/to/config.json(최우선)
뒤에서 읽은 파일의 값이 앞의 값을 덮어씁니다.
{
"defaults": {
"max_diff_bytes": 120000,
"system_prompt": "You are a strict senior code reviewer. Output Markdown with sections: Critical, Major, Minor, Suggestions.",
"review_guide_path": ".repopilot/review-guide.md",
"comment_language": "ko",
"update_check_url": "https://gitlab.your-company.com/api/v4/projects/<PROJECT_ID>/releases/permalink/latest",
"update_download_url": "https://gitlab.your-company.com/your-group/your-project/-/releases",
"update_timeout_ms": 1200
},
"hosts": {
"github.com": {
"token_env": "GITHUB_TOKEN",
"token_command": ["gh", "auth", "token"]
},
"gitlab.com": {
"token_env": "GITLAB_TOKEN",
"token_command": ["glab", "auth", "token"]
}
},
"providers": {
"openai": {
"enabled": true,
"api_key_env": "OPENAI_API_KEY",
"model": "gpt-4.1-mini",
"command": "codex",
"args": ["exec"],
"auto_auth": true,
"auth_command": ["codex", "login"]
},
"anthropic": {
"enabled": true,
"api_key_env": "ANTHROPIC_API_KEY",
"model": "claude-3-7-sonnet-latest",
"command": "claude",
"use_stdin": false,
"args": ["-p", "{prompt}"],
"auto_auth": true,
"auth_command": ["claude", "auth", "login"]
},
"gemini": {
"enabled": true,
"api_key_env": "GEMINI_API_KEY",
"model": "gemini-2.0-flash",
"command": "gemini",
"use_stdin": false,
"args": ["-p", "{prompt}"],
"auto_auth": true,
"auth_command": ["gemini"]
}
}
}enabled: provider 사용 여부 (true/false)api_key/api_key_env: API 인증 키(또는 OAuth access token) 값/환경변수api_base(선택): API 베이스 URL overridemodel(선택): provider 기본 모델 IDcommand: CLI 모드에서 실행할 로컬 명령 이름 또는 경로args: CLI 모드 명령 인자 배열use_stdin(선택): CLI 모드에서 프롬프트 전달 시 기본값trueauto_auth(선택): CLI 모드에서 인증 오류 감지 시auth_command를 1회 실행 후 재시도(기본true, TTY에서만 동작)auth_command(선택): OAuth/로그인용 커맨드 배열(예:["codex","login"],["claude","auth","login"],["gemini"])defaults.review_guide_path: 리뷰 지침 Markdown 파일 경로. 내용이 system prompt에 추가됨defaults.comment_language: 리뷰 결과 언어 (ko또는en, 기본값ko)defaults.update_check_url: 최신 버전 확인 endpoint (plain text 버전 문자열 또는 JSON)defaults.update_download_url: 업데이트 안내에 출력할 다운로드 URL (선택)defaults.update_timeout_ms: 업데이트 체크 타임아웃(ms, 기본1200)
추가 규칙:
api_key또는api_key_env가 설정되면 API 모드가 우선 사용됨- API 키가 없을 때만 CLI 모드(
command/args)를 사용함 use_stdin=false일 때args안에{prompt}가 있으면 치환해서 전달use_stdin=false이고{prompt}가 없으면 프롬프트 문자열을 마지막 인자로 자동 추가
repopilot config출력(JSON)에는 다음 정보가 포함됩니다.
- 탐색한 config 경로 목록 (
searched_paths) - 실제 로드된 경로 목록 (
loaded_paths) - 원본 defaults (
defaults) - 폴백 포함 최종 defaults (
effective_defaults) - host별 토큰 소스/해결 여부
- provider별 resolved mode(api/cli), runnable 여부, command/args/use_stdin 정보
특정 파일로 강제 테스트:
REPOPILOT_CONFIG=/tmp/config.json repopilot config각 대상의 HEAD SHA마다 기존 코멘트/노트에서 아래 마커를 확인합니다.
- final marker:
<!-- repopilot-bot sha=<SHA> --> - claim marker:
<!-- repopilot-bot claim sha=<SHA> -->
동작 순서:
- 현재 HEAD SHA 조회
- 동일 SHA의 마커가 이미 있으면 스킵 (
--force면 진행) - 없으면 claim 코멘트/노트 생성 또는 업데이트
- provider들을 병렬로 실행
- claim 코멘트/노트를 최종 리뷰 코멘트로 업데이트
- 실제 코멘트 작성에는 해당 host의 VCS 토큰이 필요합니다.
--dry-run은 코멘트 작성은 하지 않지만, private 저장소에서는 API 읽기 권한이 여전히 필요할 수 있습니다.- diff가
defaults.max_diff_bytes를 초과하면 잘리고... (diff truncated)문구가 추가됩니다. - API key가 설정되지 않았고 provider 커맨드가 PATH에서 발견되지 않으면 해당 provider는 자동 제외됩니다.
- 일부 CLI가
stdin is not a terminal오류를 내면 CLI 모드에서 stdin 없는 방식으로 1회 재시도합니다. - 1차 리뷰/상호 코멘트 프롬프트는 영어로 구성되며, 최종 출력 언어는
defaults.comment_language값으로 제어됩니다. defaults.update_check_url이 설정되어 있으면 실행 시작 시 최신 버전이 있는지 확인하고, 새 버전이 있으면 업데이트 안내를 출력합니다.