一个面向 GitHub Pull Request 场景的浏览器扩展,由 Java 后端安全地完成 Diff 抓取和 AI 调用。
扩展读取当前 PR 或 Compare 页面的 URL,将它交给 Spring Boot 服务;Java 后端抓取 Git Diff、调用兼容 OpenAI Chat Completions 协议的模型,并把结构化 PR 描述返回给扩展。用户可以预览结果,再一键回填到 GitHub 描述输入框。
旧版本完全在浏览器侧运行,API Key 保存在 chrome.storage.local,Diff 也由扩展直接发送给模型服务。现在这些职责已经迁入 Java 后端:
- AI API Key 只存在于服务端环境变量中
- Prompt、Diff 截断、重试和模型错误处理集中维护
- 扩展不再需要模型服务域名权限
- 可用一个后端为团队统一模型和生成模板
- 可选配置 GitHub Token,以读取后端有权访问的私有仓库
主链路如下:
- 扩展读取当前 GitHub PR 或 Compare 页面 URL
- 扩展调用 Java 后端的
POST /api/pr-descriptions - 后端校验 URL,仅允许从
github.com抓取对应 Diff - 后端截断超长 Diff,组合统一 Prompt,并调用 AI Chat Completions 接口
- 扩展预览返回的 Markdown,并可一键写回 GitHub PR 描述框
- 浏览器扩展:React 18、TypeScript、Plasmo
- 后端:Java 21、Spring Boot 4.1、Maven
- 模型协议:OpenAI-compatible Chat Completions
- 部署:可执行 JAR 或 Docker
.
├── backend/
│ ├── src/main/java/ # Controller、GitHub Diff、AI Client、配置与安全
│ ├── src/test/java/ # Java 单元测试和 Spring 上下文测试
│ ├── Dockerfile
│ └── pom.xml
├── lib/
│ ├── backend.ts # 扩展调用 Java API
│ └── settings.ts # 后端地址和访问令牌的浏览器本地配置
├── popup.tsx # 扩展弹窗和 GitHub 回填逻辑
├── compose.yaml
└── package.json
- Node.js 18+
- npm
- Java 21 和 Maven 3.6.3+,或 Docker
- Chrome 或其他 Chromium 浏览器
- 可用的 AI API Key
推荐使用 Docker:
cp backend/.env.example backend/.env在 backend/.env 至少填写:
AI_API_KEY=your_api_key_here
AI_BASE_URL=https://api.moonshot.cn/v1
AI_MODEL=moonshot-v1-8k
APP_SECURITY_TOKEN=replace_with_a_long_random_token然后启动:
docker compose up --build也可以直接使用本地 Java:
cd backend
export AI_API_KEY=your_api_key_here
export AI_BASE_URL=https://api.moonshot.cn/v1
export AI_MODEL=moonshot-v1-8k
mvn spring-boot:run服务默认监听 http://localhost:8080。检查状态:
curl http://localhost:8080/api/health如果配置了 APP_SECURITY_TOKEN,请求需要携带:
X-Backend-Token: <你的令牌>
在仓库根目录执行:
npm install
npm run dev在 Chrome 的 chrome://extensions 中开启开发者模式,点击“加载已解压的扩展程序”,选择:
build/chrome-mv3-dev
打开扩展的“设置”页:
- Java 后端地址:本地默认
http://localhost:8080 - 后端访问令牌:如果后端配置了
APP_SECURITY_TOKEN,这里填写相同值;否则留空
保存时,扩展会按后端域名申请运行时权限。扩展本地不再保存 AI API Key、模型名或模型接口地址。
- 打开
https://github.com/<owner>/<repo>/pull/<number>或 Compare 页面 - 打开扩展,点击“一键生成 PR 描述”
- Java 后端抓取 Diff 并生成结果
- 在弹窗中检查 Markdown
- 展开 GitHub 的 PR 描述编辑框,点击“一键粘贴到 GitHub 描述框”
当前输出结构为:
## 📝 描述## 🛠 改动清单## 影响范围
GET /api/health示例响应:
{
"status": "ok",
"aiConfigured": true,
"model": "moonshot-v1-8k"
}POST /api/pr-descriptions
Content-Type: application/json
{
"githubUrl": "https://github.com/owner/repo/pull/123"
}示例响应:
{
"content": "## 📝 描述\n- ..."
}POST /api/ai/test| 环境变量 | 默认值 | 说明 |
|---|---|---|
AI_API_KEY |
空 | 必填,模型服务密钥 |
AI_BASE_URL |
https://api.moonshot.cn/v1 |
模型服务基础地址 |
AI_API_URL |
空 | 完整 Chat Completions 地址,设置后优先于 Base URL |
AI_MODEL |
moonshot-v1-8k |
模型名 |
AI_MAX_ATTEMPTS |
3 |
对限流和过载错误的最大尝试次数 |
AI_RETRY_DELAY |
1200ms |
线性退避的基础延迟 |
AI_REQUEST_TIMEOUT |
90s |
模型请求超时 |
GITHUB_TOKEN |
空 | 可选;读取私有仓库或提高 GitHub API 配额 |
GITHUB_DIFF_CHARACTER_LIMIT |
15000 |
发送给模型的最大 Diff 字符数 |
APP_SECURITY_TOKEN |
空 | 可选;保护 Java API 的共享令牌,部署时建议配置 |
PORT |
8080 |
服务端口 |
没有 GITHUB_TOKEN 时,后端通过公开 .diff 地址读取公开仓库。配置 Token 后,后端改用 GitHub API,因此可以读取该 Token 有权访问的私有仓库。
- 后端只接受主机名严格为
github.com的 PR / Compare URL,避免将服务变成任意 URL 代理。 - CORS 默认允许 Chrome 扩展以及本机开发地址。
- 本地单人使用可以不设置
APP_SECURITY_TOKEN;部署到公网时应配置强随机令牌,并在反向代理层启用 HTTPS、限流和访问日志。 - Java 后端持有 AI Key,也会接触 Diff 内容;团队部署时应由可信环境托管。
Java 后端测试:
npm run backend:test扩展生产构建:
npm run build后端打包:
cd backend
mvn package
java -jar target/ai-pr-helper-backend-0.1.0.jar扩展打包:
npm run package- Java 后端代理 AI 请求,浏览器不再保存 AI API Key
- 服务端抓取和截断 Git Diff
- 服务端重试限流和过载错误
- 支持可选后端访问令牌
- 支持可选 GitHub Token 和私有仓库
- 支持超长 Diff 分段总结
- 支持自定义 Prompt / 模板
- 支持中英文输出切换
- 增加生成历史和持久化
- 增加服务端指标、限流与链路追踪
请参阅 CONTRIBUTING.md。项目使用 MIT License。