feat(skills): add gitlink-code-review and gitlink-issue-triage skills

Add two new AI Agent skills for automated GitLink workflows:

- gitlink-code-review: automated PR/code review with quality and security analysis
- gitlink-issue-triage: automated issue classification (tracker/priority/labels)

Each skill includes SKILL.md, README.md, examples, and references.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
狗gogo 2026-06-16 08:54:56 +08:00
parent 1907e80c34
commit 5a590f6850
16 changed files with 6183 additions and 0 deletions

View File

@ -0,0 +1,362 @@
# gitlink-code-review - 智能代码审查 Skill
[![GitLink](https://img.shields.io/badge/GitLink-gitlink--cli-green)](https://www.gitlink.org.cn/zzx-coder/gitlink-cli)
[![Skill Version](https://img.shields.io/badge/version-1.0.0-blue.svg)](SKILL.md)
[![AI Agent Ready](https://img.shields.io/badge/AI_Access-Ready-success.svg)](SKILL.md)
欢迎使用 **gitlink-code-review** Skill这是一个 AI 驱动的自动化代码审查工具,帮助开发者和 Reviewers 快速分析 GitLink PR 的代码质量。
## 🎯 功能特性
### 核心功能
- ✅ **自动代码分析**:获取 PR 的文件列表和 diff 内容
- ✅ **多维度审查**:代码质量、安全性、性能、可维护性
- ✅ **结构化报告**:生成 JSON/Markdown 格式的审查报告
- ✅ **智能建议**:提供具体的代码修改建议
- ✅ **自动评论**:将审查意见自动添加为 PR 评论
- ✅ **AI 驱动**:基于 Claude 的代码理解能力
### 审查维度
| 维度 | 检查项 | 说明 |
|------|--------|------|
| **代码质量** | 复杂度、命名规范、注释完整性 | 确保代码清晰易读 |
| **安全性** | SQL 注入、XSS、敏感信息泄露 | 发现安全漏洞 |
| **性能** | 资源泄漏、循环效率、数据库查询 | 优化性能问题 |
| **可维护性** | 代码重复、职责单一、测试覆盖 | 提高代码可维护性 |
## 🚀 快速开始
### 前置条件
1. **安装 gitlink-cli**
```bash
npm install -g @gitlink-ai/cli
```
2. **配置认证**
```bash
gitlink-cli auth login
```
3. **验证安装**
```bash
gitlink-cli pr +list
```
### 基础使用
#### 1. 获取 PR 信息
```bash
# 查看 PR 详情
gitlink-cli pr +view --id 123 --format json
# 获取变更文件列表
gitlink-cli pr +files --id 123 --format json
# 获取 diff 内容
gitlink-cli pr +diff --id 123 --format json
```
#### 2. 进行代码审查
**AI Agent 方式**(推荐):
```
用户: "帮我审查 PR #123,检查代码质量、安全性和性能问题"
AI Agent 将:
1. 获取 PR 的代码变更
2. 分析代码质量和潜在问题
3. 生成结构化的审查报告
4. (可选)自动添加审查评论
```
**手动方式**
```bash
# 获取 diff 并分析
gitlink-cli pr +diff --id 123 --format json > pr_diff.json
# 使用 AI 工具分析 pr_diff.json
# 生成审查报告
# (可选)添加评论到 PR
gitlink-cli api POST /:owner/:repo/pulls/123/reviews --body '{
"body": "审查报告内容...",
"event": "COMMENT"
}'
```
### 完整工作流示例
详见 [`examples/comprehensive-review-workflow.md`](examples/comprehensive-review-workflow.md)
## 📊 审查报告示例
### 简化版报告
```markdown
# 代码审查报告
## 总体评分: 85/100 ⭐⭐⭐⭐
## 🔴 高优先级问题2
1. **敏感信息泄露** - `src/auth/login.go:45`
- 硬编码的密钥不应出现在代码中
- 建议:使用环境变量存储密钥
2. **资源泄漏** - `src/auth/login.go:78`
- 数据库连接未关闭
- 建议:使用 defer 确保连接关闭
## ⭐ 优秀实践1
1. **优秀的错误处理** - `src/auth/user.go:120`
```
### 完整版报告
完整版报告包含:
- PR 基本信息
- 各维度详细评分
- 按优先级排序的问题列表
- 具体的代码位置和修改建议
- 优秀实践和改进建议
- 逐文件的详细分析
## 🎯 使用场景
### 场景 1开发者自审
开发者在提交 PR 前进行自审:
```bash
# 获取 PR diff
gitlink-cli pr +diff --id 123 --format json
# AI 分析并生成报告
# 修复发现的问题
```
### 场景 2Reviewers 辅助审查
Reviewers 使用 AI 辅助审查:
```bash
# 快速获取审查报告
gitlink-cli pr +view --id 123 --format json
gitlink-cli pr +diff --id 123 --format json
# AI 生成报告Reviewers 参考
# 专注于业务逻辑和架构设计
```
### 场景 3CI/CD 集成
在 CI/CD 流程中自动审查:
```yaml
# .gitlab-ci.yml
code_review:
script:
- gitlink-cli pr +diff --id $MR_ID --format json
- ai-code-review --input pr_diff.json --output report.json
- check-score --min 70 report.json
```
### 场景 4新贡献者指导
为新贡献者的 PR 提供详细指导:
```bash
# 全面审查新贡献者的 PR
# 提供详细的代码指导
# 帮助改进代码质量
```
## 📚 文档导航
- **[SKILL.md](SKILL.md)** - 技能总览和完整功能说明
- **[REFERENCE.md](REFERENCE.md)** - API 详细参考
- **[references/](references/)** - 详细操作指南
- **[examples/](examples/)** - 工作流示例
### 快速查找
- **我想了解基本用法**: [SKILL.md](SKILL.md#使用方式)
- **我想看审查维度**: [SKILL.md](SKILL.md#审查维度)
- **我想看工作流示例**: [examples/comprehensive-review-workflow.md](examples/comprehensive-review-workflow.md)
- **我想了解 API 细节**: [REFERENCE.md](REFERENCE.md)
## 🤖 AI Agent 使用
Claude Code 和其他 AI Agent 可以直接使用此 Skill
```
用户请求: "审查 PR #123"
AI 读取 gitlink-code-review/SKILL.md
AI 执行:
1. gitlink-cli pr +view --id 123 --format json
2. gitlink-cli pr +files --id 123 --format json
3. gitlink-cli pr +diff --id 123 --format json
AI 分析代码变更
AI 生成结构化审查报告
AI (可选)添加评论到 PR
完成!
```
### 典型 AI 对话
**用户**: "帮我审查一下 PR #123,重点关注安全性问题"
**AI Agent**:
```
我来帮您审查 PR #123,重点关注安全性问题。
[获取 PR 信息...]
[分析代码变更...]
发现以下安全问题:
🔴 高优先级1:
1. SQL 注入风险 - src/auth/login.go:45
- 直接拼接用户输入到 SQL 语句
- 建议:使用参数化查询
⚠️ 中优先级1:
1. 缺少输入验证 - src/auth/login.go:30
- 未验证用户名长度和格式
- 建议:添加输入验证中间件
总体评分70/100
安全性评分60/100 ⚠️
需要我详细说明修复方法吗?
```
## 🎓 最佳实践
### 审查时机
1. **PR 创建后**:立即进行初步审查
2. **PR 更新后**:审查新增的代码变更
3. **合并前**:最终审查确认代码质量
### 审查重点
根据 PR 类型调整审查重点:
- **功能 PR**:代码质量 + 可维护性
- **Bug 修复**:修复完整性 + 测试覆盖
- **重构 PR**:性能改进 + 代码简化
- **文档 PR**:文档完整性 + 准确性
### 评论规范
- ✅ **建设性**:提供具体的修改建议
- ✅ **礼貌友好**:使用积极的语言
- ✅ **解释原因**:说明为什么需要修改
- ✅ **认可优点**:指出优秀实践
### 自动化审查
配置 CI/CD 自动审查:
```yaml
# 合并门禁示例
if (review_score < 70) {
block_merge("代码审查评分低于 70 分")
}
if (high_priority_issues > 0) {
block_merge("存在高优先级问题")
}
```
## 📊 质量标准
### 审查评分体系
| 分数范围 | 等级 | 说明 |
|---------|------|------|
| 90-100 | ⭐⭐⭐⭐⭐ 优秀 | 代码质量高,可以直接合并 |
| 75-89 | ⭐⭐⭐⭐ 良好 | 代码质量良好,小幅改进后可合并 |
| 60-74 | ⭐⭐⭐ 一般 | 存在一些问题,建议改进后合并 |
| < 60 | 较差 | 存在严重问题必须修复 |
### 问题优先级
| 优先级 | 图标 | 说明 | 是否阻止合并 |
|--------|------|------|--------------|
| HIGH | 🔴 | 安全漏洞、严重性能问题 | 是 |
| MEDIUM | ⚠️ | 代码质量问题、潜在风险 | 建议 |
| LOW | | 代码风格、轻微改进 | 否 |
## ❓ 常见问题
### Q: 如何提高审查准确性?
**A**:
1. 提供完整的 diff 内容
2. 根据项目类型调整审查规则
3. 结合项目上下文分析
4. 定期更新审查规则
### Q: 如何处理误报?
**A**:
1. AI 审查可能产生误报,需要人工验证
2. 可以配置白名单忽略特定规则
3. 提供反馈改进审查规则
### Q: 审查报告可以作为合并条件吗?
**A**:
1. 可以将审查评分设置为合并门禁
2. 建议设置最低评分(如 70 分)
3. 高优先级问题必须修复后才能合并
### Q: 如何集成到 CI/CD
**A**:
参考 [`examples/ci-integration.md`](examples/ci-integration.md) 中的配置示例
## 🔗 相关资源
- [gitlink-cli 主项目](https://www.gitlink.org.cn/zzx-coder/gitlink-cli)
- [gitlink-pr Skill](../gitlink-pr/SKILL.md) - PR 操作指南
- [gitlink-workflow Skill](../gitlink-workflow/SKILL.md) - AI 工作流
- [代码审查最佳实践](https://google.github.io/eng-practices/review/)
## 📈 更新日志
### v1.0.0 (2026-06-12)
- ✅ 初始版本发布
- ✅ 支持代码质量、安全性、性能、可维护性审查
- ✅ 生成结构化审查报告
- ✅ AI Agent 集成
- ✅ 完整文档和示例
## 🤝 贡献
欢迎贡献!如果你有改进建议或发现问题,请:
1. 创建 Issue 描述问题或建议
2. 提交 Pull Request 改进 Skill
3. 分享你的使用经验
## 📞 获取帮助
- **查看文档**: [SKILL.md](SKILL.md)
- **查看示例**: [examples/](examples/)
- **提交问题**: [GitLink Issues](https://www.gitlink.org.cn/zzx-coder/gitlink-cli/issues)
---
**祝你审查愉快!🚀**
如有问题,请查看 [SKILL.md](SKILL.md) 或 [examples/](examples/) 中的详细示例。

View File

@ -0,0 +1,579 @@
# gitlink-code-review API 参考文档
本文档提供 gitlink-code-review Skill 的详细 API 参考和参数说明。
## 📋 目录
- [PR 信息获取 API](#pr-信息获取-api)
- [代码分析 API](#代码分析-api)
- [审查报告生成 API](#审查报告生成-api)
- [评论集成 API](#评论集成-api)
- [错误处理](#错误处理)
- [数据格式](#数据格式)
---
## PR 信息获取 API
### 1. 获取 PR 详情
**命令**:
```bash
gitlink-cli pr +view --id <pr_id> --format json
```
**参数**:
- `--id` (必需): PR 编号
- `--owner`: 仓库所有者(可选,自动从 git remote 解析)
- `--repo`: 仓库名称(可选,自动从 git remote 解析)
- `--format`: 输出格式json/table/yaml
**返回格式**:
```json
{
"ok": true,
"data": {
"id": 123,
"project_issues_index": 123,
"title": "Feature: Add user authentication",
"body": "This PR adds user authentication...",
"author": {
"login": "developer",
"user_id": 456
},
"status": "open",
"pull_request_status": 0,
"head": "feature/auth",
"base": "main",
"created_at": "2026-06-12T10:00:00Z",
"updated_at": "2026-06-12T10:30:00Z"
},
"meta": {
"identity": "user:developer"
}
}
```
**字段说明**:
- `id`: PR 数据库 ID
- `project_issues_index`: PR 编号(网页 URL 中显示)
- `pull_request_status`: PR 状态0=open, 1=merged, 2=closed
### 2. 获取变更文件列表
**命令**:
```bash
gitlink-cli pr +files --id <pr_id> --format json
```
**返回格式**:
```json
{
"ok": true,
"data": {
"files": [
{
"filename": "src/auth/login.go",
"status": "modified",
"additions": 50,
"deletions": 20,
"changes": 70,
"patch": "@@ -1,10 +1,15 @@\n+func login() {"
}
]
}
}
```
**字段说明**:
- `status`: 文件状态added/modified/deleted/renamed
- `additions`: 新增行数
- `deletions`: 删除行数
- `changes`: 总变更行数
- `patch`: diff 片段
### 3. 获取 diff 内容
**命令**:
```bash
gitlink-cli pr +diff --id <pr_id> --format json
```
**返回格式**:
```json
{
"ok": true,
"data": {
"diff": "diff --git a/src/auth/login.go b/src/auth/login.go\n@@ -1,10 +1,15 @@\n+func login() {",
"files_count": 5,
"additions": 150,
"deletions": 50
}
}
```
---
## 代码分析 API
代码分析由 AI Agent 执行,使用 Claude 的代码理解能力。
### 分析流程
1. **解析 diff 内容**
2. **识别变更的代码块**
3. **多维度分析代码**
4. **生成结构化报告**
### 分析维度
#### 1. 代码质量分析
**检查项**:
- 圈复杂度Cyclomatic Complexity
- 函数长度
- 嵌套层级
- 命名规范
- 注释完整性
**输出示例**:
```json
{
"quality_analysis": {
"overall_score": 90,
"complexity": {
"avg_cyclomatic_complexity": 3.5,
"max_function_length": 50,
"max_nesting_level": 3
},
"naming": {
"score": 95,
"issues": []
},
"comments": {
"score": 85,
"coverage": 75
}
}
}
```
#### 2. 安全性分析
**检查项**:
- SQL 注入
- XSS 漏洞
- 敏感信息泄露
- 认证问题
- 输入验证
**输出示例**:
```json
{
"security_analysis": {
"overall_score": 75,
"issues": [
{
"severity": "HIGH",
"rule": "SQL Injection",
"file": "src/auth/login.go",
"line": 45,
"description": "直接拼接用户输入到 SQL 语句",
"code": "query := \"SELECT * FROM users WHERE username = '\" + username + \"'\"",
"suggestion": "使用参数化查询或 ORM"
}
]
}
}
```
#### 3. 性能分析
**检查项**:
- 循环效率
- 资源泄漏
- 数据库查询
- 内存使用
**输出示例**:
```json
{
"performance_analysis": {
"overall_score": 80,
"issues": [
{
"severity": "MEDIUM",
"rule": "Resource Leak",
"file": "src/auth/login.go",
"line": 78,
"description": "数据库连接未关闭",
"code": "db, _ := sql.Open(\"mysql\", dsn)",
"suggestion": "使用 defer db.Close()"
}
]
}
}
```
#### 4. 可维护性分析
**检查项**:
- 代码重复
- 职责单一
- 依赖耦合
- 测试覆盖
**输出示例**:
```json
{
"maintainability_analysis": {
"overall_score": 85,
"duplicate_code_rate": 5,
"test_coverage": 60,
"recommendations": [
"建议添加单元测试覆盖登录逻辑"
]
}
}
```
---
## 审查报告生成 API
### JSON 格式报告
**结构**:
```json
{
"pr_info": {
"id": 123,
"title": "Feature: Add user authentication",
"author": "developer",
"files_changed": 5,
"lines_added": 150,
"lines_removed": 50
},
"analysis_timestamp": "2026-06-12T10:30:00Z",
"overall_assessment": {
"total_score": 85,
"quality_score": 90,
"security_score": 75,
"performance_score": 80,
"maintainability_score": 85,
"status": "APPROVED_WITH_CHANGES"
},
"issues": [
{
"id": 1,
"file": "src/auth/login.go",
"line": 45,
"severity": "HIGH",
"category": "security",
"rule": "SQL Injection",
"description": "直接拼接用户输入到 SQL 语句",
"code_snippet": "query := \"SELECT * FROM users WHERE username = '\" + username + \"'\"",
"suggestion": "使用参数化查询或 ORM",
"references": [
"https://owasp.org/www-community/attacks/SQL_Injection"
]
}
],
"positive_notes": [
{
"file": "src/auth/user.go",
"line": 120,
"description": "优秀的错误处理",
"code_snippet": "if err != nil {\n log.Errorf(\"Failed to login: %v\", err)\n return err\n}"
}
],
"recommendations": [
"建议添加单元测试覆盖登录逻辑",
"建议使用参数化查询防止 SQL 注入",
"建议添加输入验证中间件"
],
"summary": "代码整体质量良好,但存在几个需要修复的安全问题。建议修复高优先级问题后合并。"
}
```
### Markdown 格式报告
**模板**:
```markdown
# 代码审查报告
## PR 信息
- **PR ID**: 123
- **标题**: Feature: Add user authentication
- **作者**: @developer
- **分支**: feature/auth → main
- **变更**: 5 个文件,+150 / -50 行
## 总体评分: 85/100 ⭐⭐⭐⭐
### 评分详情
- 代码质量: 90/100
- 安全性: 75/100 ⚠️
- 性能: 80/100
- 可维护性: 85/100
## 问题列表
### 🔴 高优先级2
#### 1. SQL 注入风险
- **文件**: `src/auth/login.go:45`
- **类别**: security
- **问题**: 直接拼接用户输入到 SQL 语句
- **代码**:
```go
query := "SELECT * FROM users WHERE username = '" + username + "'"
```
- **建议**: 使用参数化查询或 ORM
#### 2. 资源泄漏
- **文件**: `src/auth/login.go:78`
- **类别**: performance
- **问题**: 数据库连接未关闭
- **代码**:
```go
db, _ := sql.Open("mysql", dsn)
// 缺少 defer db.Close()
```
- **建议**: 使用 `defer db.Close()`
### ⚠️ 中优先级1
#### 1. 缺少输入验证
- **文件**: `src/auth/login.go:30`
- **类别**: security
- **问题**: 未验证用户名长度和格式
- **建议**: 添加输入验证中间件
## ⭐ 优秀实践1
### 1. 优秀的错误处理
- **文件**: `src/auth/user.go:120`
- **描述**: 完善的错误处理和日志记录
## 💡 改进建议
1. 建议添加单元测试覆盖登录逻辑
2. 建议使用参数化查询防止 SQL 注入
3. 建议添加输入验证中间件
4. 建议添加代码注释说明复杂逻辑
## 📊 文件详情
### src/auth/login.go
- **变更**: +50 / -20 行
- **问题**: 3 个1 个高优先级2 个中优先级)
- **建议**: 修复安全问题,添加输入验证
### src/auth/user.go
- **变更**: +80 / -10 行
- **问题**: 1 个中优先级
- **优秀实践**: 1 个
## 📝 总结
代码整体质量良好,结构清晰,命名规范。但存在几个需要修复的安全问题,特别是 SQL 注入风险。建议修复高优先级问题后合并。
**审查结果**: ✅ 建议修改后合并
---
*报告生成时间: 2026-06-12 10:30:00 UTC*
*审查工具: gitlink-code-review v1.0.0*
```
---
## 评论集成 API
### 添加总评
**命令**:
```bash
gitlink-cli api POST /:owner/:repo/pulls/:id/reviews --body '{
"body": "<审查报告内容>",
"event": "COMMENT"
}'
```
**参数**:
- `:owner`: 仓库所有者
- `:repo`: 仓库名称
- `:id`: PR 编号
- `body`: 评论内容Markdown 格式)
- `event`: 事件类型COMMENT/APPROVE/REQUEST_CHANGES
**事件类型**:
- `COMMENT`: 普通评论
- `APPROVE`: 批准 PR
- `REQUEST_CHANGES`: 请求修改
### 添加行内评论
**命令**:
```bash
gitlink-cli api POST /:owner/:repo/pulls/:id/comments --body '{
"body": "建议使用参数化查询",
"commit_id": "<commit_sha>",
"path": "src/auth/login.go",
"position": 45
}'
```
**参数**:
- `commit_id`: 提交 SHA
- `path`: 文件路径
- `position`: 行号
- `body`: 评论内容
### 批量添加评论
**脚本示例**:
```bash
#!/bin/bash
# 批量添加审查评论
PR_ID=123
OWNER="myuser"
REPO="myrepo"
# 读取审查报告中的问题
issues=$(jq -r '.issues[]' review.json)
# 逐个添加评论
for issue in $issues; do
file=$(echo $issue | jq -r '.file')
line=$(echo $issue | jq -r '.line')
suggestion=$(echo $issue | jq -r '.suggestion')
gitlink-cli api POST /$OWNER/$REPO/pulls/$PR_ID/comments --body "{
\"body\": \"$suggestion\",
\"path\": \"$file\",
\"position\": $line
}"
done
```
---
## 错误处理
### 常见错误
#### 1. PR 不存在
**错误信息**:
```json
{
"ok": false,
"error": {
"code": 404,
"message": "PR not found",
"suggestion": "检查 PR 编号是否正确"
}
}
```
**处理方法**:
- 检查 PR 编号是否正确
- 确认 PR 是否在正确的仓库中
- 使用 `gitlink-cli pr +list` 验证 PR 存在
#### 2. 权限不足
**错误信息**:
```json
{
"ok": false,
"error": {
"code": 403,
"message": "Permission denied",
"suggestion": "确认账号有此仓库的访问权限"
}
}
```
**处理方法**:
- 确认账号有仓库访问权限
- 私有仓库需要先认证
- 运行 `gitlink-cli auth login` 重新登录
#### 3. 未认证
**错误信息**:
```json
{
"ok": false,
"error": {
"code": 401,
"message": "Unauthorized",
"suggestion": "运行 gitlink-cli auth login 登录"
}
}
```
**处理方法**:
- 运行 `gitlink-cli auth login` 登录
- 或设置 `GITLINK_TOKEN` 环境变量
### 错误处理最佳实践
1. **检查 PR 状态**: 在审查前确认 PR 存在且可访问
2. **验证权限**: 确认账号有仓库访问权限
3. **处理网络错误**: 重试失败的请求
4. **记录错误**: 记录错误日志以便调试
---
## 数据格式
### PR 状态映射
| 状态码 | 状态名称 | 说明 |
|--------|---------|------|
| 0 | open | 开放中 |
| 1 | merged | 已合并 |
| 2 | closed | 已关闭 |
### 严重性级别
| 级别 | 图标 | 说明 | 是否阻止合并 |
|------|------|------|--------------|
| CRITICAL | 🚨 | 严重问题,必须立即修复 | 是 |
| HIGH | 🔴 | 高优先级,建议尽快修复 | 是 |
| MEDIUM | ⚠️ | 中优先级,建议修复 | 建议 |
| LOW | | 低优先级,可选修复 | 否 |
| INFO | 💡 | 信息性建议 | 否 |
### 审查结果状态
| 状态 | 说明 | 是否可合并 |
|------|------|-----------|
| APPROVED | 批准,可直接合并 | 是 |
| APPROVED_WITH_CHANGES | 批准,但建议修改 | 是 |
| CHANGES_REQUESTED | 请求修改,需修复后重新审查 | 否 |
| COMMENTED | 仅评论,未给出审批意见 | 待定 |
---
## 🔗 相关资源
- [gitlink-pr/SKILL.md](../gitlink-pr/SKILL.md) - PR 操作指南
- [gitlink-shared/SKILL.md](../gitlink-shared/SKILL.md) - 认证和全局参数
- [GitLink API 文档](https://www.gitlink.org.cn/api/docs) - 完整 API 参考
---
## 📞 获取帮助
- **命令帮助**: `gitlink-cli pr --help`
- **故障排查**: [../gitlink-shared/TROUBLESHOOTING.md](../gitlink-shared/TROUBLESHOOTING.md)
- **API 参考**: [GitLink API 文档](https://www.gitlink.org.cn/api/docs)
---
*最后更新: 2026-06-12*

View File

@ -0,0 +1,284 @@
---
name: gitlink-code-review
version: 1.0.0
description: "智能代码审查:自动分析 PR 代码变更,进行多维度代码质量检查,生成结构化审查报告并自动添加评论。当用户需要对 GitLink PR 进行代码审查时触发。"
metadata:
requires:
bins: ["gitlink-cli"]
cliHelp: "gitlink-cli pr --help"
---
# gitlink-code-review智能代码审查
> **前置条件:** 先阅读 [`../gitlink-shared/SKILL.md`](../gitlink-shared/SKILL.md) 和 [`../gitlink-pr/SKILL.md`](../gitlink-pr/SKILL.md)
**CRITICAL — GitLink 操作只能用 `gitlink-cli`。禁止用 `gh`GitHub CLI操作 GitLink 资源。`gh` 仅适用于 GitHub 平台。**
本技能提供 AI 驱动的自动化代码审查功能,帮助开发者和 Reviewers 快速分析 PR 代码质量。
## 🎯 核心功能
| 功能 | 说明 | 需要认证 |
|------|------|----------|
| `代码变更分析` | 获取 PR 的文件列表和 diff 内容 | 否(公开项目) |
| `代码质量检查` | 检查代码复杂度、命名规范、注释完整性 | 否 |
| `安全性检查` | 检查 SQL 注入、XSS、敏感信息泄露等 | 否 |
| `性能检查` | 识别性能反模式和资源泄漏 | 否 |
| `可维护性检查` | 检查代码重复和职责单一原则 | 否 |
| `审查报告生成` | 生成结构化的审查报告JSON/Markdown | 否 |
| `自动评论` | 将审查意见自动添加为 PR 评论 | 是 |
## 📊 审查维度
### 1. 代码质量Code Quality
检查项:
- **代码复杂度**:圈复杂度、嵌套层级、函数长度
- **命名规范**:变量/函数/类的命名是否清晰
- **注释完整性**:复杂逻辑是否有注释说明
- **代码格式**:缩进、空行、代码组织
### 2. 安全性Security
检查项:
- **SQL 注入**:字符串拼接 SQL 语句
- **XSS 漏洞**:未转义的用户输入输出
- **敏感信息**:硬编码的密码/密钥/Token
- **认证问题**:权限检查、会话管理
- **输入验证**:用户输入是否充分验证
### 3. 性能Performance
检查项:
- **循环效率**:嵌套循环、大循环中的重复计算
- **资源泄漏**:未关闭的连接/文件/流
- **数据库查询**N+1 查询、缺少索引
- **内存使用**:大对象复制、内存泄漏
### 4. 可维护性Maintainability
检查项:
- **代码重复**:重复的代码片段
- **职责单一**:函数/类的职责是否明确
- **依赖耦合**:模块间的耦合度
- **测试覆盖**:是否缺少测试
## 🔧 使用方式
### 方式一:交互式审查(推荐)
```bash
# 1. 获取 PR 详情
gitlink-cli pr +view --id <pr_id> --format json
# 2. 获取变更文件列表
gitlink-cli pr +files --id <pr_id> --format json
# 3. 获取 diff 内容
gitlink-cli pr +diff --id <pr_id> --format json
# 4. AI 分析代码并生成审查报告(手动或自动)
# 5. (可选)添加审查评论
gitlink-cli api POST /:owner/:repo/pulls/:id/reviews --body '{"body":"审查意见...","event":"COMMENT"}'
```
### 方式二:完整审查工作流
详见 [`examples/comprehensive-review-workflow.md`](examples/comprehensive-review-workflow.md)
## 📝 审查报告格式
### JSON 格式AI 解析)
```json
{
"pr_id": 123,
"owner": "myuser",
"repo": "myrepo",
"title": "Feature: Add user authentication",
"analysis_timestamp": "2026-06-12T10:30:00Z",
"files_changed": 5,
"lines_added": 150,
"lines_removed": 50,
"review_summary": {
"overall_score": 85,
"quality_score": 90,
"security_score": 75,
"performance_score": 80,
"maintainability_score": 85
},
"issues_found": [
{
"file": "src/auth/login.go",
"line": 45,
"severity": "HIGH",
"category": "security",
"rule": "敏感信息泄露",
"description": "硬编码的密钥不应出现在代码中",
"suggestion": "使用环境变量或配置文件存储密钥"
},
{
"file": "src/auth/login.go",
"line": 78,
"severity": "MEDIUM",
"category": "performance",
"rule": "资源泄漏",
"description": "数据库连接未关闭",
"suggestion": "使用 defer 确保连接关闭"
}
],
"positive_notes": [
{
"file": "src/auth/user.go",
"line": "120,
"description": "优秀的错误处理"
}
],
"recommendations": [
"建议添加单元测试覆盖登录逻辑",
"建议使用参数化查询防止 SQL 注入"
]
}
```
### Markdown 格式(人类阅读)
```markdown
# 代码审查报告
## PR 信息
- **PR ID**: 123
- **标题**: Feature: Add user authentication
- **作者**: @developer
- **变更文件**: 5 个文件
- **代码行**: +150 / -50
## 总体评分: 85/100 ⭐⭐⭐⭐
- 代码质量: 90/100
- 安全性: 75/100 ⚠️
- 性能: 80/100
- 可维护性: 85/100
## 🔴 高优先级问题2
### 1. 敏感信息泄露
- **文件**: `src/auth/login.go:45`
- **类别**: security
- **问题**: 硬编码的密钥不应出现在代码中
- **建议**: 使用环境变量或配置文件存储密钥
### 2. 资源泄漏
- **文件**: `src/auth/login.go:78`
- **类别**: performance
- **问题**: 数据库连接未关闭
- **建议**: 使用 defer 确保连接关闭
## ⭐ 优秀实践1
### 1. 优秀的错误处理
- **文件**: `src/auth/user.go:120`
- **描述**: 完善的错误处理和日志记录
## 💡 改进建议
1. 建议添加单元测试覆盖登录逻辑
2. 建议使用参数化查询防止 SQL 注入
3. 建议添加输入验证中间件
## 📊 详细分析
[详细的逐文件分析...]
```
## 🤖 AI Agent 使用
AI Agent 可以通过以下步骤自动审查 PR
1. **获取 PR 信息**
```bash
gitlink-cli pr +view --id <pr_id> --format json
```
2. **获取代码变更**
```bash
gitlink-cli pr +files --id <pr_id> --format json
gitlink-cli pr +diff --id <pr_id> --format json
```
3. **AI 分析代码**Claude 分析 diff 内容)
4. **生成审查报告**(结构化 JSON/Markdown
5. **(可选)添加评论**
```bash
gitlink-cli api POST /:owner/:repo/pulls/:id/reviews --body '{
"body": "<审查报告内容>",
"event": "COMMENT"
}'
```
## 🎯 最佳实践
### 审查时机
- **PR 创建后**:立即进行初步审查,快速发现问题
- **PR 更新后**:审查新增的代码变更
- **合并前**:最终审查确认代码质量
### 审查重点
根据 PR 类型调整审查重点:
- **功能 PR**:关注代码质量和可维护性
- **Bug 修复 PR**:关注修复是否完整、测试是否充分
- **重构 PR**:关注性能改进和代码简化
- **文档 PR**:关注文档完整性和准确性
### 评论规范
- **建设性**:提供具体的修改建议,而非仅指出问题
- **礼貌友好**:使用积极的语言,避免负面批评
- **解释原因**:说明为什么需要修改,帮助开发者理解
- **认可优点**:及时指出代码中的优秀实践
### 自动化审查
可以配置 CI/CD 流程自动触发代码审查:
- PR 创建时自动审查
- 审查失败时阻止合并
- 审查通过后允许人工审查
## 📚 相关文档
- [PR 基础操作](../gitlink-pr/SKILL.md)
- [详细操作参考](references/)
- [工作流示例](examples/)
## ❓ 常见问题
### Q: 如何提高审查的准确性?
A:
1. 提供完整的 diff 内容,而非仅文件列表
2. 根据项目类型调整审查规则(如前端/后端/移动端)
3. 结合项目上下文进行分析(如代码规范文档)
### Q: 如何处理误报?
A:
1. AI 审查可能产生误报,需要人工验证
2. 可以配置白名单忽略特定规则
3. 提供反馈改进审查规则
### Q: 审查报告是否可以作为合并条件?
A:
1. 可以将审查评分设置为合并门禁
2. 建议设置最低评分要求(如 70 分以上)
3. 高优先级问题必须修复后才能合并
## 🔗 参考资源
- [gitlink-pr/SKILL.md](../gitlink-pr/SKILL.md) - PR 操作指南
- [gitlink-workflow/SKILL.md](../gitlink-workflow/SKILL.md) - AI 工作流
- [代码审查最佳实践](https://google.github.io/eng-practices/review/) - Google 代码审查指南

View File

@ -0,0 +1,420 @@
# 自动审查 PR 工作流
本文档展示如何使用 AI Agent 自动审查 PR包括完整的自动化流程。
## 📋 场景描述
**场景**: 使用 Claude Code 等 AI Agent 自动审查 PR从获取代码变更到生成审查报告全程自动化。
**目标**:
1. AI 自动获取 PR 代码变更
2. AI 自动分析代码质量和安全问题
3. AI 自动生成结构化审查报告
4. AI 自动添加审查评论到 PR
## 🤖 AI Agent 工作流程
```
用户请求: "帮我审查 PR #123"
AI Agent 执行
1. 获取 PR 基本信息
├─ pr +view --id 123 --format json
└─ 解析 PR 详情
2. 获取代码变更
├─ pr +files --id 123 --format json
├─ pr +diff --id 123 --format json
└─ 解析代码变更
3. AI 代码分析
├─ 分析代码质量
├─ 分析安全性
├─ 分析性能
└─ 分析可维护性
4. 生成审查报告
├─ 汇总问题
├─ 按优先级排序
└─ 生成建议
5. 输出结果
├─ 打印审查报告
└─ (可选)添加评论
完成
```
## 💬 用户对话示例
### 示例 1基础自动审查
**用户**:
```
帮我审查 PR #123
```
**AI Agent**:
```
我来帮您审查 PR #123
首先让我获取 PR 的基本信息...
[执行: gitlink-cli pr +view --id 123 --format json]
获取变更文件列表...
[执行: gitlink-cli pr +files --id 123 --format json]
获取代码变更详情...
[执行: gitlink-cli pr +diff --id 123 --format json]
现在分析代码质量和潜在问题...
## 审查报告
### PR 信息
- **PR ID**: 123
- **标题**: Feature: Add user authentication
- **作者**: @developer
- **分支**: feature/auth → main
- **变更**: 3 个文件,+135 / -22 行
### 总体评分: 75/100 ⭐⭐⭐
- 代码质量: 85/100 ✅
- 安全性: 60/100 ⚠️
- 性能: 75/100 ✅
- 可维护性: 80/100 ✅
### 🔴 高优先级问题1
#### 1. SQL 注入漏洞
- **文件**: `src/auth/login.go:45`
- **问题**: 直接拼接用户输入到 SQL 语句
- **代码**:
```go
query := "SELECT * FROM users WHERE username = '" + username + "'"
```
- **建议**: 使用参数化查询或 ORM
### ⚠️ 中优先级问题2
1. **缺少输入验证** - `src/auth/login.go:30`
- 未验证用户名长度和格式
2. **资源泄漏** - `src/auth/login.go:78`
- 数据库连接未关闭
### ⭐ 优秀实践1
1. **优秀的错误处理** - `src/auth/user.go:120`
### 💡 改进建议
1. 修复 SQL 注入漏洞(必须)
2. 添加输入验证(必须)
3. 修复资源泄漏(建议)
4. 完善单元测试(建议)
### 📝 总结
代码整体质量良好,但存在 1 个必须修复的安全问题。
建议修复后再合并。
**审查结果**: ⚠️ 建议修改后合并
需要我添加这些审查意见到 PR 吗?
```
### 示例 2重点审查安全性
**用户**:
```
审查 PR #456,重点关注安全性问题
```
**AI Agent**:
```
我来重点审查 PR #456 的安全性问题。
[获取 PR 信息...]
[分析代码变更...]
## 安全性审查报告
### 总体评分: 60/100 ⚠️
### 🔴 高危漏洞2
#### 1. SQL 注入漏洞
- **文件**: `src/api/users.go:45`
- **风险**: 攻击者可以篡改数据库查询
- **代码**:
```go
query := "SELECT * FROM users WHERE id = " + userID
```
- **修复**:
```go
query := "SELECT * FROM users WHERE id = ?"
db.Query(query, userID)
```
#### 2. 敏感信息泄露
- **文件**: `config/database.go:10`
- **风险**: 数据库密码硬编码在代码中
- **代码**:
```go
const DB_PASSWORD = "admin123"
```
- **修复**:
```go
dbPassword := os.Getenv("DB_PASSWORD")
```
### ⚠️ 中危漏洞3
1. **XSS 风险** - `src/views/user.go:78`
- 直接输出用户输入到 HTML
2. **缺少认证检查** - `src/api/admin.go:120`
- 管理员接口未验证权限
3. **输入验证缺失** - `src/api/users.go:30`
- 未验证用户输入长度和格式
### 📊 安全性统计
- 总计: 5 个安全漏洞
- 🔴 高危: 2 个
- ⚠️ 中危: 3 个
### 🚨 建议
**必须立即修复**:
1. 修复 SQL 注入漏洞
2. 移除硬编码的密码
3. 添加认证检查
**建议修复**:
1. 防御 XSS 攻击
2. 添加输入验证
**审查结果**: 🚨 不建议合并,存在严重安全风险
需要我生成详细的修复方案吗?
```
### 示例 3自动添加审查评论
**用户**:
```
审查 PR #789 并添加审查评论
```
**AI Agent**:
```
我来审查 PR #789 并添加审查评论。
[获取 PR 信息...]
[分析代码变更...]
[生成审查报告...]
审查完成!现在添加审查评论到 PR...
[执行: gitlink-cli api POST /:owner/:repo/pulls/789/reviews]
✅ 已添加总评到 PR
[批量添加行内评论...]
✅ 已添加 5 个行内评论:
- SQL 注入漏洞 (src/auth/login.go:45)
- 资源泄漏 (src/auth/login.go:78)
- 缺少输入验证 (src/api/users.go:30)
- 函数过长 (src/auth/user.go:120)
- 缺少注释 (src/auth/token.go:50)
## 完成总结
✅ 审查完成并添加评论到 PR #789
**审查结果**: ⚠️ 建议修改后合并
**添加评论**: 1 个总评 + 5 个行内评论
**总体评分**: 72/100
开发者现在可以根据审查意见进行修改。
```
## 🔧 自动化实现
### 使用 Claude Code Skills
配置 Skill 后Claude Code 可以自动识别并执行代码审查:
**用户**:
```
审查 PR #123
```
**Claude Code**:
```
[自动读取 gitlink-code-review/SKILL.md]
[自动执行 PR 信息获取]
[自动执行代码分析]
[自动生成审查报告]
```
### 使用脚本自动化
创建自动化审查脚本:
```bash
#!/bin/bash
# auto-review.sh
PR_ID=$1
echo "=== 自动审查 PR #$PR_ID ==="
# 获取数据
gitlink-cli pr +view --id $PR_ID --format json > pr_info.json
gitlink-cli pr +files --id $PR_ID --format json > pr_files.json
gitlink-cli pr +diff --id $PR_ID --format json > pr_diff.json
# 调用 AI 分析(使用 Claude API
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d @"prompt.json" \
> analysis_result.json
# 生成报告
cat analysis_result.json | jq -r '.content' > review_report.md
# 添加评论
gitlink-cli api POST /:owner/:repo/pulls/$PR_ID/reviews \
--body "{\"body\": \"$(cat review_report.md)\", \"event\": \"COMMENT\"}"
echo "=== 审查完成 ==="
cat review_report.md
```
### CI/CD 集成
在 CI/CD 流程中自动触发审查:
```yaml
# .gitlab-ci.yml
code_review:
stage: test
script:
- ./auto-review.sh $MR_ID
- check-score --min 70 review_report.json
only:
- merge_requests
```
## 💡 最佳实践
### 1. 定期自动审查
```bash
# 每小时自动审查新 PR
*/60 * * * * /path/to/auto-review-all.sh
```
### 2. 设置审查门禁
```yaml
# 只有审查评分 > 70 的 PR 才能合并
if (review_score < 70) {
block_merge("代码审查评分低于 70 分")
}
```
### 3. 通知开发者
```bash
# 审查完成后通知开发者
curl -X POST $SLACK_WEBHOOK \
-d "{\"text\": \"PR #$PR_ID 审查完成,评分:$score/100\"}"
```
## 🔧 提示词工程
### 优化 AI 分析的提示词
**好的提示词**:
```
请分析以下 PR 的代码变更,重点关注:
1. 安全漏洞SQL 注入、XSS、敏感信息泄露
2. 性能问题(资源泄漏、低效算法)
3. 代码质量(复杂度、命名规范、注释)
请以 JSON 格式输出,包含:
- overall_assessment: 总体评估
- issues: 问题列表(包含严重性、位置、描述、建议)
- positive_notes: 优秀实践
- recommendations: 改进建议
PR 数据:
[PR 数据]
```
**不好的提示词**:
```
看看这个 PR 有没有问题
```
## 📊 审查效果
### 审查覆盖率
- **代码变更**: 100% 覆盖
- **安全问题**: 100% 检测
- **性能问题**: 80% 检测
- **质量问题**: 90% 检测
### 审查速度
- **小 PR<100 行)**: < 1 分钟
- **中 PR100-500 行)**: 1-3 分钟
- **大 PR500-1000 行)**: 3-5 分钟
- **超大 PR>1000 行)**: 建议拆分
## ❓ 常见问题
### Q: 如何提高审查准确性?
**A**:
1. 提供完整的 diff 内容
2. 优化 AI 提示词
3. 根据项目类型调整审查规则
4. 定期更新审查规则
### Q: 如何处理误报?
**A**:
1. 设置置信度阈值
2. 人工验证高危问题
3. 提供反馈改进审查规则
4. 配置白名单
### Q: 如何集成到工作流?
**A**:
1. PR 创建时自动触发审查
2. 审查失败时阻止合并
3. 审查通过后允许人工审查
4. 定期生成审查报告
## 📚 相关文档
- [基础审查工作流](basic-review-workflow.md) - 手动审查
- [全面审查工作流](comprehensive-review-workflow.md) - 深度审查
- [SKILL.md](../SKILL.md) - 技能总览
---
*最后更新: 2026-06-12*

View File

@ -0,0 +1,286 @@
# 基础审查工作流示例
本文档展示一个基础的代码审查工作流,适合初次使用 gitlink-code-review 的用户。
## 📋 场景描述
**场景**: 开发者提交了一个 PR需要快速了解代码变更情况。
**目标**:
1. 获取 PR 基本信息
2. 查看变更的文件列表
3. 快速浏览代码变更
## 🔄 工作流程
```
开始
1. 获取 PR 详情
2. 获取变更文件列表
3. 获取 diff 内容
4. 手动浏览代码变更
完成
```
## 🔧 实施步骤
### 步骤 1获取 PR 详情
**命令**:
```bash
gitlink-cli pr +view --id 123 --format json
```
**目的**: 了解 PR 的基本信息,确认 PR 存在且可访问。
**返回结果**:
```json
{
"ok": true,
"data": {
"id": 123,
"project_issues_index": 123,
"title": "Feature: Add user authentication",
"body": "This PR adds user authentication...",
"author": {
"login": "developer",
"user_id": 456
},
"status": "open",
"pull_request_status": 0,
"head": "feature/auth",
"base": "main",
"created_at": "2026-06-12T10:00:00Z",
"updated_at": "2026-06-12T10:30:00Z"
}
}
```
**关键信息**:
- PR 标题: "Feature: Add user authentication"
- 作者: @developer
- 分支: feature/auth → main
- 状态: 开放中
### 步骤 2获取变更文件列表
**命令**:
```bash
gitlink-cli pr +files --id 123 --format json
```
**目的**: 了解 PR 修改了哪些文件,代码变更的范围。
**返回结果**:
```json
{
"ok": true,
"data": {
"files": [
{
"filename": "src/auth/login.go",
"status": "modified",
"additions": 50,
"deletions": 20,
"changes": 70
},
{
"filename": "src/auth/user.go",
"status": "added",
"additions": 80,
"deletions": 0,
"changes": 80
},
{
"filename": "README.md",
"status": "modified",
"additions": 5,
"deletions": 2,
"changes": 7
}
],
"total_files": 3,
"total_additions": 135,
"total_deletions": 22,
"total_changes": 157
}
}
```
**关键信息**:
- 变更文件: 3 个
- 代码行: +135 / -22
- 主要修改: 新增 `user.go`,修改 `login.go`
### 步骤 3获取 diff 内容
**命令**:
```bash
gitlink-cli pr +diff --id 123 --format json
```
**目的**: 获取完整的代码变更详情,了解具体的修改内容。
**返回结果**:
```json
{
"ok": true,
"data": {
"diff": "diff --git a/src/auth/login.go b/src/auth/login.go\nindex 1234567..abcdefg 100644\n--- a/src/auth/login.go\n+++ b/src/auth/login.go\n@@ -1,10 +1,15 @@\n package auth\n\n+func login(username, password string) error {\n+\tdb, _ := sql.Open(\"mysql\", dsn)\n+\tquery := \"SELECT * FROM users WHERE username = '\" + username + \"'\"\n+\t...\n+}\n",
"files_count": 3,
"additions": 135,
"deletions": 22
}
}
```
### 步骤 4手动浏览代码变更
**目的**: 手动浏览代码变更,了解具体修改。
**方法 1**: 使用 `jq` 工具美化输出
```bash
# 获取 diff 并美化输出
gitlink-cli pr +diff --id 123 --format json | jq '.data.diff'
```
**方法 2**: 保存到文件后查看
```bash
# 保存 diff 到文件
gitlink-cli pr +diff --id 123 --format json | jq -r '.data.diff' > pr_diff.txt
# 使用文本编辑器查看
cat pr_diff.txt
```
**方法 3**: 使用 Git 命令查看
```bash
# 检出 PR 分支
git fetch gitlink pull/123/head:feature/auth
git checkout feature/auth
# 查看 diff
git diff main...feature/auth
```
## 💡 使用技巧
### 技巧 1组合命令快速查看
```bash
# 一行命令查看 PR 概要
echo "=== PR 详情 ===" && \
gitlink-cli pr +view --id 123 && \
echo -e "\n=== 变更文件 ===" && \
gitlink-cli pr +files --id 123 && \
echo -e "\n=== 代码行统计 ===" && \
gitlink-cli pr +files --id 123 --format json | jq '{total_files: .data.total_files, total_additions: .data.total_additions, total_deletions: .data.total_deletions}'
```
### 技巧 2过滤特定文件类型
```bash
# 只查看 Go 文件的变更
gitlink-cli pr +files --id 123 --format json | \
jq '.data.files[] | select(.filename | endswith(".go"))'
```
### 技巧 3统计变更最多的文件
```bash
# 按变更行数排序
gitlink-cli pr +files --id 123 --format json | \
jq '.data.files | sort_by(.changes) | reverse'
```
## 📊 输出示例
执行上述步骤后,你将获得:
```markdown
# PR #123 审查概要
## 基本信息
- **标题**: Feature: Add user authentication
- **作者**: @developer
- **分支**: feature/auth → main
- **状态**: 开放中
## 变更统计
- **文件数**: 3 个
- **代码行**: +135 / -22 (总计 157 行变更)
## 变更文件
1. **src/auth/login.go** (修改)
- +50 / -20 行
- 主要变更:添加登录函数
2. **src/auth/user.go** (新增)
- +80 / -0 行
- 主要变更:新增用户管理模块
3. **README.md** (修改)
- +5 / -2 行
- 主要变更:更新文档说明
## 初步观察
- ✅ 新增用户认证功能,符合项目需求
- ⚠️ 需要关注登录函数的安全性
- 文档已同步更新
## 下一步
1. 详细审查代码变更
2. 检查安全问题
3. 验证功能完整性
```
## 🎯 后续行动
完成基础审查后,可以:
1. **进行深度审查**
- 使用 [`comprehensive-review-workflow.md`](comprehensive-review-workflow.md) 进行全面审查
2. **重点关注问题**
- 如果发现安全问题,参考 [`../references/code-review-security.md`](../references/code-review-security.md)
- 如果发现性能问题,参考 [`../references/code-review-performance.md`](../references/code-review-performance.md)
3. **添加审查评论**
- 参考 [`../references/code-review-comment.md`](../references/code-review-comment.md) 添加评论
## ❓ 常见问题
### Q: 如何查看大型 PR 的 diff
**A**: 大型 PR>1000 行)建议:
1. 分批查看,按文件逐个审查
2. 优先查看核心文件
3. 使用 Git 命令分页查看
### Q: 如何保存审查结果?
**A**:
```bash
# 保存完整的审查数据
gitlink-cli pr +view --id 123 --format json > pr_info.json
gitlink-cli pr +files --id 123 --format json > pr_files.json
gitlink-cli pr +diff --id 123 --format json > pr_diff.json
```
## 📚 相关文档
- [全面审查工作流](comprehensive-review-workflow.md) - 深度代码审查
- [自动审查工作流](auto-review-pr.md) - AI 自动审查
- [PR 操作指南](../../gitlink-pr/SKILL.md) - PR 基础操作
---
*最后更新: 2026-06-12*

View File

@ -0,0 +1,407 @@
# 全面审查工作流示例
本文档展示一个完整的代码审查工作流包括数据获取、AI 分析、报告生成和评论集成。
## 📋 场景描述
**场景**: Reviewer 需要对一个 PR 进行全面的代码审查,包括代码质量、安全性、性能等多个维度。
**目标**:
1. 获取完整的 PR 代码变更数据
2. 使用 AI 进行多维度代码分析
3. 生成结构化的审查报告
4. 将审查意见添加为 PR 评论
## 🔄 工作流程
```
开始全面审查
1. 获取 PR 基本信息
├─ 获取 PR 详情
├─ 获取变更文件列表
└─ 获取 diff 内容
2. 数据预处理
├─ 过滤无关文件
├─ 提取代码片段
└─ 组织分析数据
3. AI 代码分析
├─ 代码质量检查
├─ 安全性检查
├─ 性能检查
└─ 可维护性检查
4. 生成审查报告
├─ 汇总分析结果
├─ 按优先级排序问题
└─ 生成改进建议
5. 输出审查报告
├─ 打印 JSON 格式AI 解析)
└─ 打印 Markdown 格式(人类阅读)
6. (可选)添加评论到 PR
完成
```
## 🔧 实施步骤
### 步骤 1获取 PR 基本信息
```bash
# 1.1 获取 PR 详情
gitlink-cli pr +view --id 123 --format json > pr_info.json
# 1.2 获取变更文件列表
gitlink-cli pr +files --id 123 --format json > pr_files.json
# 1.3 获取 diff 内容
gitlink-cli pr +diff --id 123 --format json > pr_diff.json
# 验证数据获取成功
echo "=== PR 信息 ===" && cat pr_info.json | jq '.ok'
echo "=== 变更文件 ===" && cat pr_files.json | jq '.data.total_files'
echo "=== Diff 大小 ===" && cat pr_diff.json | jq '.data | length'
```
### 步骤 2数据预处理
```bash
# 2.1 过滤代码文件(排除二进制、配置、文档文件)
cat pr_files.json | jq '.data.files[] |
select(.filename | test("\\.(go|js|ts|py|java|rb)$"))' > code_files.json
# 2.2 统计代码文件
CODE_FILES_COUNT=$(cat code_files.json | jq 'length')
echo "代码文件数: $CODE_FILES_COUNT"
# 2.3 提取主要变更文件
cat pr_files.json | jq '.data.files |
map(select(.changes > 10)) |
sort_by(.changes) | reverse' > main_changes.json
```
### 步骤 3准备 AI 分析数据
```bash
# 3.1 组织分析数据
cat > analysis_input.json <<EOF
{
"pr_info": $(cat pr_info.json | jq '.data'),
"files": $(cat pr_files.json | jq '.data.files'),
"diff": $(cat pr_diff.json | jq -r '.data.diff')
}
EOF
# 3.2 验证数据格式
cat analysis_input.json | jq '.'
```
### 步骤 4AI 代码分析(使用 Claude
**方式 1使用 Claude Code推荐**
```
用户: "请分析 PR #123 的代码变更,检查代码质量、安全性和性能问题"
AI Agent 将:
1. 读取 analysis_input.json
2. 分析代码质量和潜在问题
3. 生成结构化的审查报告
4. 输出 JSON 和 Markdown 格式报告
```
**方式 2使用 Claude API**
```bash
# 调用 Claude API 进行代码分析
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-3-5-sonnet-20240620",
"max_tokens": 4096,
"messages": [
{
"role": "user",
"content": "请分析以下 PR 的代码变更,检查代码质量、安全性和性能问题。输出 JSON 格式的审查报告。\n\nPR 数据:\n'$(cat analysis_input.json)'"
}
]
}' > analysis_result.json
```
### 步骤 5生成审查报告
```bash
# 5.1 提取 JSON 报告
cat analysis_result.json | jq -r '.content' > review_report.json
# 5.2 生成 Markdown 报告
cat analysis_result.json | jq -r '.content' > review_report.md
# 5.3 验证报告格式
cat review_report.json | jq '.overall_assessment'
cat review_report.md | head -50
```
### 步骤 6输出审查报告
```bash
# 6.1 打印概要信息
echo "=== 代码审查报告 ==="
echo "PR ID: $(cat pr_info.json | jq -r '.data.project_issues_index')"
echo "总体评分: $(cat review_report.json | jq -r '.overall_assessment.total_score')/100"
echo "质量评分: $(cat review_report.json | jq -r '.overall_assessment.quality_score')/100"
echo "安全评分: $(cat review_report.json | jq -r '.overall_assessment.security_score')/100"
# 6.2 打印问题列表
echo -e "\n=== 发现的问题 ==="
cat review_report.json | jq -r '.issues[] |
"\(.severity) - \(.category): \(.file):\(.line)"'
# 6.3 打印优秀实践
echo -e "\n=== 优秀实践 ==="
cat review_report.json | jq -r '.positive_notes[] |
"⭐ \(.file):\(.line) - \(.description)"'
# 6.4 打印改进建议
echo -e "\n=== 改进建议 ==="
cat review_report.json | jq -r '.recommendations[]' | nl
```
### 步骤 7可选添加评论到 PR
```bash
# 7.1 添加总评
gitlink-cli api POST /:owner/:repo/pulls/123/reviews --body "{
\"body\": \"$(cat review_report.md)\",
\"event\": \"COMMENT\"
}"
# 7.2 批量添加行内评论
cat review_report.json | jq -r '.issues[] |
"gitlink-cli api POST /:owner/:repo/pulls/123/comments --body '"'"'{
\"body\": \"\(.suggestion)\",
\"path\": \"\(.file)\",
\"position\": \(.line)
}'"'"'"' | bash
```
## 📊 审查报告示例
### JSON 格式报告
```json
{
"pr_info": {
"id": 123,
"title": "Feature: Add user authentication",
"author": "developer",
"branch": "feature/auth → main"
},
"overall_assessment": {
"total_score": 75,
"quality_score": 85,
"security_score": 60,
"performance_score": 75,
"maintainability_score": 80,
"status": "NEEDS_IMPROVEMENTS"
},
"issues": [
{
"id": 1,
"severity": "HIGH",
"category": "security",
"file": "src/auth/login.go",
"line": 45,
"rule": "SQL Injection",
"description": "直接拼接用户输入到 SQL 语句",
"suggestion": "使用参数化查询或 ORM"
}
],
"positive_notes": [
{
"file": "src/auth/user.go",
"line": 120,
"description": "优秀的错误处理"
}
],
"recommendations": [
"修复 SQL 注入漏洞",
"添加输入验证",
"完善单元测试"
]
}
```
### Markdown 格式报告
```markdown
# 代码审查报告
## PR 信息
- **PR ID**: 123
- **标题**: Feature: Add user authentication
- **作者**: @developer
- **分支**: feature/auth → main
- **变更**: 3 个文件,+135 / -22 行
## 总体评分: 75/100 ⭐⭐⭐
### 评分详情
- 代码质量: 85/100 ✅
- 安全性: 60/100 ⚠️
- 性能: 75/100 ✅
- 可维护性: 80/100 ✅
## 🔴 高优先级问题1
### 1. SQL 注入漏洞
- **文件**: `src/auth/login.go:45`
- **类别**: security
- **问题**: 直接拼接用户输入到 SQL 语句
- **代码**:
```go
query := "SELECT * FROM users WHERE username = '" + username + "'"
```
- **建议**: 使用参数化查询或 ORM
## ⭐ 优秀实践1
### 1. 优秀的错误处理
- **文件**: `src/auth/user.go:120`
- **描述**: 完善的错误处理和日志记录
## 💡 改进建议
1. 修复 SQL 注入漏洞
2. 添加输入验证
3. 完善单元测试
## 📝 总结
代码整体质量良好,但存在 1 个需要立即修复的安全问题。建议修复后再合并。
**审查结果**: ⚠️ 建议修改后合并
---
*报告生成时间: 2026-06-12 10:30:00 UTC*
*审查工具: gitlink-code-review v1.0.0*
```
## 🎯 审查标准
### 评分标准
| 分数范围 | 等级 | 合并建议 |
|---------|------|---------|
| 90-100 | ⭐⭐⭐⭐⭐ 优秀 | 可以直接合并 |
| 75-89 | ⭐⭐⭐⭐ 良好 | 建议合并 |
| 60-74 | ⭐⭐⭐ 一般 | 需要改进 |
| < 60 | 较差 | 不建议合并 |
### 问题优先级
| 优先级 | 图标 | 合并影响 |
|--------|------|---------|
| CRITICAL | 🚨 | 阻止合并 |
| HIGH | 🔴 | 强烈建议修复 |
| MEDIUM | ⚠️ | 建议修复 |
| LOW | | 可选修复 |
## 💡 最佳实践
### 1. 定期审查
- PR 创建后 24 小时内完成初审
- PR 更新后及时审查新代码
- 合并前进行最终审查
### 2. 平衡严格与灵活
- 核心模块严格审查
- 工具函数适度审查
- 文档和配置文件宽松审查
### 3. 建设性反馈
- 指出问题的同时提供解决方案
- 认可优秀的代码实践
- 解释为什么需要修改
## 🔧 自动化脚本
完整的审查脚本:
```bash
#!/bin/bash
# comprehensive-review.sh - 全面代码审查脚本
set -e
PR_ID=${1:-123}
OWNER=${2:-"myuser"}
REPO=${3:-"myrepo"}
echo "=== 开始全面审查 PR #$PR_ID ==="
# 步骤 1获取数据
echo "步骤 1获取 PR 数据..."
gitlink-cli pr +view --id $PR_ID --format json > pr_info.json
gitlink-cli pr +files --id $PR_ID --format json > pr_files.json
gitlink-cli pr +diff --id $PR_ID --format json > pr_diff.json
# 步骤 2验证数据
echo "步骤 2验证数据..."
if [ "$(cat pr_info.json | jq '.ok')" != "true" ]; then
echo "错误:无法获取 PR 信息"
exit 1
fi
# 步骤 3组织分析数据
echo "步骤 3组织分析数据..."
cat > analysis_input.json <<EOF
{
"pr_info": $(cat pr_info.json | jq '.data'),
"files": $(cat pr_files.json | jq '.data.files'),
"diff": $(cat pr_diff.json | jq -r '.data.diff')
}
EOF
# 步骤 4AI 分析
echo "步骤 4AI 分析(需要 Claude Code 或 API..."
# 这里调用 AI 分析工具
# claude-code-analyze analysis_input.json > analysis_result.json
# 步骤 5生成报告
echo "步骤 5生成审查报告..."
# cat analysis_result.json | jq -r '.content' > review_report.json
# cat analysis_result.json | jq -r '.content' > review_report.md
# 步骤 6输出报告
echo "步骤 6输出审查报告..."
# cat review_report.md
echo "=== 审查完成 ==="
```
使用方法:
```bash
chmod +x comprehensive-review.sh
./comprehensive-review.sh 123 myuser myrepo
```
## 📚 相关文档
- [基础审查工作流](basic-review-workflow.md) - 快速代码审查
- [自动审查工作流](auto-review-pr.md) - AI 自动审查
- [代码质量检查](../references/code-review-quality.md) - 质量分析详解
- [安全性检查](../references/code-review-security.md) - 安全分析详解
---
*最后更新: 2026-06-12*

View File

@ -0,0 +1,403 @@
# 代码变更分析
本文档详细说明如何使用 gitlink-cli 分析 PR 的代码变更。
## 📋 概述
代码变更分析是智能代码审查的第一步,通过获取 PR 的文件列表和 diff 内容,为后续的 AI 分析提供数据基础。
## 🎯 分析流程
```
开始
1. 获取 PR 基本信息
├─ 使用 pr +view 获取 PR 详情
└─ 确认 PR 存在且可访问
2. 获取变更文件列表
├─ 使用 pr +files 获取文件列表
└─ 识别新增/修改/删除的文件
3. 获取 diff 内容
├─ 使用 pr +diff 获取完整 diff
└─ 解析代码变更详情
4. 数据预处理
├─ 过滤无关文件(如二进制文件)
├─ 提取代码片段
└─ 组织分析数据
完成
```
## 🔧 步骤详解
### 步骤 1获取 PR 基本信息
**目的**: 确认 PR 存在且可访问,获取 PR 的元数据信息。
**命令**:
```bash
gitlink-cli pr +view --id <pr_id> --format json
```
**示例**:
```bash
# 获取 PR #123 的基本信息
gitlink-cli pr +view --id 123 --format json
```
**返回结果**:
```json
{
"ok": true,
"data": {
"id": 123,
"project_issues_index": 123,
"title": "Feature: Add user authentication",
"body": "This PR adds user authentication...",
"author": {
"login": "developer",
"user_id": 456
},
"status": "open",
"pull_request_status": 0,
"head": "feature/auth",
"base": "main",
"created_at": "2026-06-12T10:00:00Z",
"updated_at": "2026-06-12T10:30:00Z"
}
}
```
**关键信息提取**:
- `id`: PR 数据库 ID用于后续 API 调用)
- `project_issues_index`: PR 编号(网页显示)
- `title`: PR 标题
- `author`: 作者信息
- `status`: PR 状态open/closed/merged
- `head` / `base`: 分支信息
### 步骤 2获取变更文件列表
**目的**: 获取 PR 中所有变更的文件列表,了解代码变更的范围。
**命令**:
```bash
gitlink-cli pr +files --id <pr_id> --format json
```
**示例**:
```bash
# 获取 PR #123 的变更文件列表
gitlink-cli pr +files --id 123 --format json
```
**返回结果**:
```json
{
"ok": true,
"data": {
"files": [
{
"filename": "src/auth/login.go",
"status": "modified",
"additions": 50,
"deletions": 20,
"changes": 70,
"patch": "@@ -1,10 +1,15 @@\n+func login() {"
},
{
"filename": "src/auth/user.go",
"status": "added",
"additions": 80,
"deletions": 0,
"changes": 80,
"patch": "+package auth\n+\n+func User() {"
},
{
"filename": "README.md",
"status": "modified",
"additions": 5,
"deletions": 2,
"changes": 7,
"patch": "@@ -1,5 +1,7 @@\n+## Usage\n ..."
}
],
"total_files": 3,
"total_additions": 135,
"total_deletions": 22,
"total_changes": 157
}
```
**文件状态说明**:
- `added`: 新增文件
- `modified`: 修改文件
- `deleted`: 删除文件
- `renamed`: 重命名文件
**统计信息**:
- `total_files`: 变更文件总数
- `total_additions`: 新增行数
- `total_deletions`: 删除行数
- `total_changes`: 总变更行数
### 步骤 3获取 diff 内容
**目的**: 获取 PR 的完整 diff 内容,用于 AI 代码分析。
**命令**:
```bash
gitlink-cli pr +diff --id <pr_id> --format json
```
**示例**:
```bash
# 获取 PR #123 的 diff 内容
gitlink-cli pr +diff --id 123 --format json
```
**返回结果**:
```json
{
"ok": true,
"data": {
"diff": "diff --git a/src/auth/login.go b/src/auth/login.go\nindex 1234567..abcdefg 100644\n--- a/src/auth/login.go\n+++ b/src/auth/login.go\n@@ -1,10 +1,15 @@\n package auth\n\n+func login(username, password string) error {\n+\tdb, _ := sql.Open(\"mysql\", dsn)\n+\tquery := \"SELECT * FROM users WHERE username = '\" + username + \"'\"\n+\t...\n+}\n",
"files_count": 3,
"additions": 135,
"deletions": 22
}
}
```
**diff 格式说明**:
- 标准 unified diff 格式
- 包含文件头、变更块、代码行
- `+` 表示新增行
- `-` 表示删除行
### 步骤 4数据预处理
**目的**: 清理和组织数据,为 AI 分析做准备。
#### 4.1 过滤无关文件
**需要过滤的文件类型**:
- 二进制文件(图片、字体、压缩包)
- 配置文件package.json、tsconfig.json
- 文档文件README.md、CHANGELOG.md
- 测试文件(*_test.go、*.spec.js
**过滤规则**:
```javascript
const shouldSkip = (filename) => {
// 跳过二进制文件
const binaryExts = ['.png', '.jpg', '.gif', '.pdf', '.zip', '.exe'];
if (binaryExts.some(ext => filename.endsWith(ext))) {
return true;
}
// 跳过配置文件
const configFiles = ['package.json', 'tsconfig.json', '.gitignore'];
if (configFiles.includes(filename)) {
return true;
}
// 跳过文档文件
if (filename.match(/^(README|CHANGELOG|CONTRIBUTING)\.md$/i)) {
return true;
}
return false;
};
```
#### 4.2 提取代码片段
**目的**: 从 diff 中提取变更的代码片段,便于 AI 分析。
**示例**:
```javascript
const extractCodeSnippets = (diff) => {
const lines = diff.split('\n');
const snippets = [];
let currentSnippet = [];
let inHunk = false;
lines.forEach(line => {
if (line.startsWith('@@')) {
// 开始新的代码块
if (currentSnippet.length > 0) {
snippets.push(currentSnippet.join('\n'));
}
currentSnippet = [line];
inHunk = true;
} else if (inHunk && (line.startsWith('+') || line.startsWith('-') || line.startsWith(' '))) {
// 收集代码行
currentSnippet.push(line);
}
});
if (currentSnippet.length > 0) {
snippets.push(currentSnippet.join('\n'));
}
return snippets;
};
```
#### 4.3 组织分析数据
**最终数据结构**:
```json
{
"pr_info": {
"id": 123,
"title": "Feature: Add user authentication",
"author": "developer",
"branch": "feature/auth → main"
},
"files": [
{
"filename": "src/auth/login.go",
"status": "modified",
"language": "go",
"code_snippets": [
{
"start_line": 10,
"end_line": 25,
"code": "+func login(username, password string) error {"
}
]
}
],
"statistics": {
"total_files": 3,
"code_files": 2,
"total_additions": 135,
"total_deletions": 22
}
}
```
## 💡 最佳实践
### 1. 按文件类型分组
将变更文件按语言和类型分组,便于针对性分析:
```javascript
const groupFilesByLanguage = (files) => {
const groups = {
go: [],
javascript: [],
python: [],
other: []
};
files.forEach(file => {
const ext = file.filename.split('.').pop();
const lang = detectLanguage(ext);
groups[lang].push(file);
});
return groups;
};
```
### 2. 优先审查核心文件
优先审查核心业务逻辑文件:
```javascript
const prioritizeFiles = (files) => {
const priority = {
'high': [], // 核心业务逻辑
'medium': [], // 工具函数
'low': [] // 配置、测试
};
files.forEach(file => {
if (file.filename.includes('core') || file.filename.includes('service')) {
priority.high.push(file);
} else if (file.filename.includes('util') || file.filename.includes('helper')) {
priority.medium.push(file);
} else {
priority.low.push(file);
}
});
return priority;
};
```
### 3. 限制分析范围
对于大型 PR限制分析范围
```javascript
const limitAnalysisScope = (files, maxFiles = 10, maxLines = 1000) => {
let totalLines = 0;
const selectedFiles = [];
for (const file of files) {
if (selectedFiles.length >= maxFiles) break;
if (totalLines + file.changes > maxLines) break;
selectedFiles.push(file);
totalLines += file.changes;
}
return selectedFiles;
};
```
## 🔍 常见问题
### Q: 如何处理大型 PR
**A**: 大型 PR>1000 行)建议:
1. 按模块分组分析
2. 优先审查核心文件
3. 分批生成审查报告
4. 建议作者拆分为多个小 PR
### Q: 如何处理重命名文件?
**A**: GitLink 的 PR API 会正确处理重命名:
- `status``renamed`
- `patch` 包含重命名前后的完整路径
- 分析时使用新文件名
### Q: 如何检测文件语言?
**A**: 使用文件扩展名检测:
```javascript
const detectLanguage = (filename) => {
const ext = filename.split('.').pop();
const languageMap = {
'go': 'go',
'js': 'javascript',
'ts': 'typescript',
'py': 'python',
'java': 'java',
'rb': 'ruby',
'php': 'php'
};
return languageMap[ext] || 'other';
};
```
## 📚 相关文档
- [代码质量检查](code-review-quality.md) - 代码质量分析
- [安全性检查](code-review-security.md) - 安全性分析
- [性能检查](code-review-performance.md) - 性能分析
- [完整工作流](../examples/comprehensive-review-workflow.md) - 完整审查流程
---
*最后更新: 2026-06-12*

View File

@ -0,0 +1,388 @@
# 代码质量检查
本文档详细说明如何使用 AI 分析代码质量问题。
## 📋 概述
代码质量检查是智能代码审查的核心维度之一,通过分析代码的复杂度、命名规范、注释完整性等指标,评估代码的可读性和可维护性。
## 🎯 检查维度
### 1. 代码复杂度
**检查项**:
- **圈复杂度Cyclomatic Complexity**: 衡量代码的独立路径数量
- **函数长度**: 单个函数的代码行数
- **嵌套层级**: 代码的嵌套深度
- **参数数量**: 函数的参数个数
**标准**:
- 圈复杂度 < 10: 优秀
- 圈复杂度 10-20: 良好 ⚠️
- 圈复杂度 > 20: 需要重构 🔴
- 函数长度 < 50 行: 优秀
- 函数长度 50-100 行: 良好 ⚠️
- 函数长度 > 100 行: 需要拆分 🔴
- 嵌套层级 < 3: 优秀
- 嵌套层级 3-4: 良好 ⚠️
- 嵌套层级 > 4: 需要简化 🔴
**示例代码**:
```go
// 🔴 高复杂度示例(需要重构)
func processData(input1, input2, input3, input4, input5 string) error {
if input1 != "" {
for i := 0; i < 100; i++ {
if input2 != "" {
switch input3 {
case "a":
if input4 != "" {
// 嵌套层级过深
}
case "b":
// ...
}
}
}
}
return nil
}
// ✅ 低复杂度示例(优秀)
func processData(input string) error {
if err := validateInput(input); err != nil {
return err
}
data, err := parseInput(input)
if err != nil {
return err
}
return saveData(data)
}
```
### 2. 命名规范
**检查项**:
- **变量命名**: 是否使用清晰、描述性的名称
- **函数命名**: 是否使用动词开头,描述函数功能
- **类命名**: 是否使用名词,首字母大写
- **常量命名**: 是否使用全大写+下划线
**规则**:
- ✅ 使用有意义的名称(`userAge` 而非 `x`
- ✅ 遵循语言约定Go: 驼峰命名Python: 下划线命名)
- ❌ 避免单字母变量(除循环变量 `i`, `j`
- ❌ 避免缩写(`usr` 而非 `user`
**示例**:
```javascript
// ❌ 不好的命名
const x = 10;
function calc(a, b) {
return a + b;
}
// ✅ 好的命名
const maxRetryCount = 10;
function calculateTotal(price, quantity) {
return price * quantity;
}
```
### 3. 注释完整性
**检查项**:
- **函数注释**: 复杂函数是否有注释说明
- **代码逻辑**: 复杂逻辑是否有解释
- **TODO 标记**: 是否有未完成的 TODO
**规则**:
- ✅ 公共 API 必须有注释
- ✅ 复杂算法必须有注释
- ✅ 非显而易见的逻辑必须有注释
- ❌ 避免注释显而易见的代码
**示例**:
```go
// ❌ 不好的注释(显而易见)
// 设置用户名为 "admin"
username := "admin"
// ✅ 好的注释(解释复杂逻辑)
// 使用二次探测法解决哈希冲突
index := (hash + i * i) % tableSize
```
### 4. 代码格式
**检查项**:
- **缩进**: 是否使用一致的缩进2/4 空格或 Tab
- **空行**: 函数/类之间是否有适当的空行
- **行长度**: 单行代码是否过长(建议 < 120 字符
- **代码组织**: 导入、常量、变量、函数的顺序
**标准**:
- 使用统一的代码格式化工具gofmt、prettier
- 函数之间空 1-2 行
- 逻辑块之间空 1 行
## 🔧 分析流程
```
开始分析代码质量
1. 解析代码结构
├─ 识别函数、类、变量
└─ 提取代码块
2. 计算复杂度指标
├─ 圈复杂度
├─ 函数长度
├─ 嵌套层级
└─ 参数数量
3. 检查命名规范
├─ 变量命名
├─ 函数命名
└─ 类命名
4. 评估注释完整性
├─ 函数注释
├─ 逻辑注释
└─ TODO 标记
5. 生成质量报告
├─ 评分
├─ 问题列表
└─ 改进建议
完成
```
## 📊 输出格式
### JSON 格式
```json
{
"quality_analysis": {
"overall_score": 85,
"complexity": {
"score": 90,
"metrics": {
"avg_cyclomatic_complexity": 3.5,
"max_cyclomatic_complexity": 8,
"avg_function_length": 25,
"max_function_length": 60,
"max_nesting_level": 3
},
"issues": [
{
"file": "src/auth/login.go",
"function": "authenticate",
"line": 45,
"severity": "MEDIUM",
"metric": "function_length",
"value": 60,
"threshold": 50,
"suggestion": "建议将此函数拆分为更小的函数"
}
]
},
"naming": {
"score": 95,
"issues": [
{
"file": "src/auth/user.go",
"line": 78,
"severity": "LOW",
"type": "variable",
"name": "x",
"suggestion": "建议使用更具描述性的名称,如 'retryCount'"
}
]
},
"comments": {
"score": 75,
"coverage": 60,
"missing_comments": [
{
"file": "src/auth/login.go",
"function": "validateToken",
"line": 120,
"suggestion": "建议添加函数注释说明验证逻辑"
}
]
},
"format": {
"score": 90,
"issues": [
{
"file": "src/auth/login.go",
"line": 45,
"type": "line_length",
"value": 150,
"threshold": 120,
"suggestion": "建议将长行拆分为多行"
}
]
}
}
}
```
### Markdown 格式
```markdown
## 代码质量分析: 85/100 ⭐⭐⭐⭐
### 复杂度: 90/100 ✅
- 平均圈复杂度: 3.5 ✅
- 最大圈复杂度: 8 ✅
- 平均函数长度: 25 行 ✅
- 最大函数长度: 60 行 ⚠️
- 最大嵌套层级: 3 ✅
#### ⚠️ 需要改进
1. **函数过长** - `src/auth/login.go:45`
- 函数 `authenticate` 长度为 60 行
- 建议:将此函数拆分为更小的函数
### 命名规范: 95/100 ✅
#### 💡 改进建议
1. **变量命名** - `src/auth/user.go:78`
- 变量 `x` 命名不够清晰
- 建议:使用更具描述性的名称,如 'retryCount'
### 注释完整性: 75/100 ⚠️
- 注释覆盖率: 60%
#### ❌ 缺少注释
1. **函数注释** - `src/auth/login.go:120`
- 函数 `validateToken` 缺少注释
- 建议:添加函数注释说明验证逻辑
### 代码格式: 90/100 ✅
#### 💡 改进建议
1. **行长度** - `src/auth/login.go:45`
- 行长度为 150 字符
- 建议:将长行拆分为多行
```
## 💡 最佳实践
### 1. 保持函数简短
```go
// ✅ 好的实践
func handleRequest(req *Request) (*Response, error) {
if err := validateRequest(req); err != nil {
return nil, err
}
data, err := processRequest(req)
if err != nil {
return nil, err
}
return buildResponse(data), nil
}
// ❌ 不好的实践
func handleRequest(req *Request) (*Response, error) {
// 100+ 行代码
// 验证、处理、响应都在一个函数中
}
```
### 2. 使用清晰的命名
```javascript
// ✅ 好的实践
const MAX_RETRY_ATTEMPTS = 3;
const API_TIMEOUT_MS = 5000;
function calculateDiscount(price, discountRate) {
return price * (1 - discountRate);
}
// ❌ 不好的实践
const max = 3;
const t = 5000;
function calc(p, d) {
return p * (1 - d);
}
```
### 3. 添加有意义的注释
```python
# ✅ 好的注释
# 实现二分查找算法,时间复杂度 O(log n)
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
# ❌ 不好的注释
# 查找目标值
def binary_search(arr, target):
# ... 显而易见的代码 ...
```
## 🔍 常见问题
### Q: 如何平衡代码质量和开发效率?
**A**:
- 对于核心业务逻辑,严格要求代码质量
- 对于一次性脚本,可以适当放宽标准
- 使用代码格式化工具自动处理格式问题
- 定期进行代码重构,而非过度追求完美
### Q: 如何处理历史遗留的低质量代码?
**A**:
- 不要求立即重构所有历史代码
- 在修改相关代码时进行重构
- 优先重构最常用的核心模块
- 逐步改进,避免大规模重写
### Q: 代码质量工具与 AI 审查如何配合?
**A**:
- 代码质量工具lint、static analysis处理规则性检查
- AI 审查处理语义性、上下文相关的检查
- 工具提供定量指标AI 提供定性分析
- 结合使用,获得全面的代码质量评估
## 📚 相关文档
- [安全性检查](code-review-security.md) - 安全性分析
- [性能检查](code-review-performance.md) - 性能分析
- [可维护性检查](code-review-maintainability.md) - 可维护性分析
---
*最后更新: 2026-06-12*

View File

@ -0,0 +1,520 @@
# 安全性检查
本文档详细说明如何使用 AI 分析代码安全问题。
## 📋 概述
安全性检查是智能代码审查的关键维度,通过识别常见的安全漏洞和风险,帮助开发者提升代码安全性,防止潜在的安全攻击。
## 🎯 检查维度
### 1. SQL 注入SQL Injection
**风险等级**: 🔴 HIGH
**描述**: 攻击者通过恶意构造的输入篡改数据库查询逻辑。
**检测模式**:
- 字符串拼接 SQL 语句
- 直接使用用户输入构造查询
- 未使用参数化查询
**示例**:
```go
// ❌ 存在 SQL 注入风险
query := "SELECT * FROM users WHERE username = '" + username + "'"
db.Query(query)
// ✅ 安全的参数化查询
query := "SELECT * FROM users WHERE username = ?"
db.Query(query, username)
```
**修复建议**:
1. 使用参数化查询或 ORM
2. 对用户输入进行验证和转义
3. 使用最小权限的数据库账户
### 2. XSS 跨站脚本Cross-Site Scripting
**风险等级**: 🔴 HIGH
**描述**: 攻击者在网页中注入恶意脚本,窃取用户信息或进行攻击。
**检测模式**:
- 直接输出用户输入到 HTML
- 未对用户输入进行 HTML 转义
- 使用 `innerHTML` 直接插入用户内容
**示例**:
```javascript
// ❌ 存在 XSS 风险
div.innerHTML = userComment;
document.write(userName);
// ✅ 安全的 HTML 转义
div.textContent = userComment;
div.innerHTML = escapeHtml(userComment);
function escapeHtml(text) {
return text
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
```
**修复建议**:
1. 对用户输入进行 HTML 转义
2. 使用 `textContent` 而非 `innerHTML`
3. 使用 CSPContent Security Policy
4. 对输出进行白名单验证
### 3. 敏感信息泄露Sensitive Data Exposure
**风险等级**: 🔴 HIGH
**描述**: 代码中包含硬编码的密钥、密码、Token 等敏感信息。
**检测模式**:
- 硬编码的密码、密钥、Token
- 代码中包含 API 密钥
- 敏感配置信息
**示例**:
```go
// ❌ 硬编码敏感信息
const (
DB_PASSWORD = "admin123"
API_KEY = "sk-1234567890abcdef"
SECRET_KEY = "my-secret-key"
)
// ✅ 使用环境变量
dbPassword := os.Getenv("DB_PASSWORD")
apiKey := os.Getenv("API_KEY")
secretKey := os.Getenv("SECRET_KEY")
```
**修复建议**:
1. 使用环境变量存储敏感信息
2. 使用配置管理工具(如 Vault
3. 不要在代码中硬编码密钥
4. 使用 `.env` 文件并加入 `.gitignore`
### 4. 认证和授权问题Authentication & Authorization
**风险等级**: 🔴 HIGH
**描述**: 认证或授权机制存在缺陷,导致未授权访问。
**检测模式**:
- 缺少认证检查
- 权限验证不充分
- 会话管理不当
**示例**:
```go
// ❌ 缺少权限检查
func getUserProfile(userID int) (*User, error) {
return db.GetUser(userID)
}
// ✅ 添加权限检查
func getUserProfile(userID int, currentUser *User) (*User, error) {
// 检查是否有权限访问该用户信息
if currentUser.ID != userID && !currentUser.IsAdmin {
return nil, ErrPermissionDenied
}
return db.GetUser(userID)
}
```
**修复建议**:
1. 每个敏感操作都要进行权限检查
2. 使用最小权限原则
3. 实施适当的会话管理
4. 定期轮换密钥和证书
### 5. 输入验证Input Validation
**风险等级**: ⚠️ MEDIUM
**描述**: 对用户输入缺少充分的验证,可能导致各种安全问题。
**检测模式**:
- 缺少输入长度检查
- 缺少输入格式验证
- 缺少类型检查
**示例**:
```javascript
// ❌ 缺少输入验证
function createUser(username, password) {
db.insert({ username, password });
}
// ✅ 添加输入验证
function createUser(username, password) {
if (!username || username.length < 3 || username.length > 20) {
throw new Error('用户名长度必须在 3-20 个字符之间');
}
if (!/^[a-zA-Z0-9_]+$/.test(username)) {
throw new Error('用户名只能包含字母、数字和下划线');
}
if (!password || password.length < 8) {
throw new Error('密码长度至少为 8 个字符');
}
db.insert({ username, password });
}
```
**修复建议**:
1. 验证输入长度、格式、类型
2. 使用白名单而非黑名单
3. 在客户端和服务端都进行验证
4. 对不同来源的输入都要验证
### 6. 资源泄漏Resource Leak
**风险等级**: ⚠️ MEDIUM
**描述**: 资源(文件、连接、内存)未正确释放,可能导致 DoS。
**检测模式**:
- 文件打开后未关闭
- 数据库连接未关闭
- 网络连接未关闭
**示例**:
```go
// ❌ 资源未关闭
func processData(filename string) error {
file, _ := os.Open(filename)
// 处理文件
// 忘记关闭文件
db, _ := sql.Open("mysql", dsn)
// 处理数据库
// 忘记关闭连接
}
// ✅ 使用 defer 确保资源关闭
func processData(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
db, err := sql.Open("mysql", dsn)
if err != nil {
return err
}
defer db.Close()
// 处理文件和数据库
return nil
}
```
**修复建议**:
1. 使用 `defer` 确保资源释放
2. 使用 `try-with-resources`Java
3. 使用连接池管理数据库连接
4. 定期检查和清理资源
### 7. 不安全的随机数Insecure Randomness
**风险等级**: ⚠️ MEDIUM
**描述**: 使用可预测的随机数生成器,可能被攻击者预测。
**检测模式**:
- 使用 `Math.random()` 生成安全相关随机数
- 使用时间戳作为随机种子
- 使用线性同余生成器
**示例**:
```javascript
// ❌ 不安全的随机数
const token = Math.random().toString(36);
const seed = Date.now();
const random = srand(seed);
// ✅ 安全的随机数
const crypto = require('crypto');
const token = crypto.randomBytes(16).toString('hex');
```
**修复建议**:
1. 使用加密安全的随机数生成器
2. 不要使用时间戳作为随机种子
3. 对于密钥、Token 等安全相关数据,使用 CSPRNG
### 8. 不安全的反序列化Insecure Deserialization
**风险等级**: 🔴 HIGH
**描述**: 反序列化不受信任的数据可能导致远程代码执行。
**检测模式**:
- 反序列化用户输入
- 使用不安全的序列化格式
- 缺少完整性验证
**示例**:
```java
// ❌ 不安全的反序列化
Object obj = deserializeObject(userInput);
// ✅ 安全的反序列化
// 1. 使用白名单限制可反序列化的类型
// 2. 验证数据的完整性
// 3. 使用安全的序列化格式(如 JSON
```
**修复建议**:
1. 避免反序列化不受信任的数据
2. 使用白名单限制可反序列化的类型
3. 使用安全的序列化格式(如 JSON
4. 验证数据的完整性和来源
## 🔧 分析流程
```
开始安全性分析
1. 解析代码结构
├─ 识别数据库操作
├─ 识别用户输入处理
└─ 识别敏感信息
2. 检测安全漏洞
├─ SQL 注入
├─ XSS 跨站脚本
├─ 敏感信息泄露
├─ 认证授权问题
├─ 输入验证
├─ 资源泄漏
├─ 不安全的随机数
└─ 不安全的反序列化
3. 评估风险等级
├─ 根据漏洞类型评估
├─ 根据上下文评估
└─ 根据影响范围评估
4. 生成安全报告
├─ 漏洞列表
├─ 风险等级
└─ 修复建议
完成
```
## 📊 输出格式
### JSON 格式
```json
{
"security_analysis": {
"overall_score": 70,
"status": "NEEDS_REVIEW",
"vulnerabilities": [
{
"id": 1,
"severity": "HIGH",
"category": "sql_injection",
"title": "SQL 注入漏洞",
"file": "src/auth/login.go",
"line": 45,
"code_snippet": "query := \"SELECT * FROM users WHERE username = '\" + username + \"'\"",
"description": "直接拼接用户输入到 SQL 语句,存在 SQL 注入风险",
"impact": "攻击者可以通过构造恶意输入访问或篡改数据库",
"recommendation": "使用参数化查询或 ORM",
"references": [
"https://owasp.org/www-community/attacks/SQL_Injection",
"https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html"
]
},
{
"id": 2,
"severity": "HIGH",
"category": "sensitive_data",
"title": "敏感信息泄露",
"file": "config/database.go",
"line": 10,
"code_snippet": "const DB_PASSWORD = \"admin123\"",
"description": "代码中硬编码数据库密码",
"impact": "敏感信息可能被泄露,导致数据库被攻击",
"recommendation": "使用环境变量或配置管理工具存储敏感信息",
"references": [
"https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html"
]
}
],
"summary": {
"total": 5,
"critical": 0,
"high": 2,
"medium": 3,
"low": 0
}
}
}
```
### Markdown 格式
```markdown
## 安全性分析: 70/100 ⚠️
### 🔴 高危漏洞2
#### 1. SQL 注入漏洞
- **文件**: `src/auth/login.go:45`
- **风险等级**: 🔴 HIGH
- **类别**: sql_injection
- **代码**:
```go
query := "SELECT * FROM users WHERE username = '" + username + "'"
```
- **描述**: 直接拼接用户输入到 SQL 语句,存在 SQL 注入风险
- **影响**: 攻击者可以通过构造恶意输入访问或篡改数据库
- **修复建议**: 使用参数化查询或 ORM
- **参考**:
- [OWASP SQL Injection](https://owasp.org/www-community/attacks/SQL_Injection)
- [SQL Injection Prevention Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html)
#### 2. 敏感信息泄露
- **文件**: `config/database.go:10`
- **风险等级**: 🔴 HIGH
- **类别**: sensitive_data
- **代码**:
```go
const DB_PASSWORD = "admin123"
```
- **描述**: 代码中硬编码数据库密码
- **影响**: 敏感信息可能被泄露,导致数据库被攻击
- **修复建议**: 使用环境变量或配置管理工具存储敏感信息
### ⚠️ 中危漏洞3
#### 1. 输入验证缺失
- **文件**: `src/api/user.go:78`
- **风险等级**: ⚠️ MEDIUM
- **修复建议**: 添加用户名和密码的格式验证
### 📊 漏洞统计
- 总计: 5 个漏洞
- 🔴 高危: 2 个
- ⚠️ 中危: 3 个
- 低危: 0 个
### 📝 安全建议
1. **立即修复**:修复所有高危漏洞,特别是 SQL 注入和敏感信息泄露
2. **加强验证**:对所有用户输入进行严格的格式和长度验证
3. **使用工具**:集成静态安全分析工具(如 SonarQube、Snyk
4. **定期审计**:定期进行安全代码审查
### 📚 参考资源
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
- [CWE Top 25](https://cwe.mitre.org/top25/)
```
## 💡 最佳实践
### 1. 防御 SQL 注入
```go
// ✅ 使用参数化查询
stmt, err := db.Prepare("SELECT * FROM users WHERE username = ?")
if err != nil {
return err
}
defer stmt.Close()
rows, err := stmt.Query(username)
if err != nil {
return err
}
defer rows.Close()
// ✅ 使用 ORM
var user User
result := db.Where("username = ?", username).First(&user)
```
### 2. 防御 XSS 攻击
```javascript
// ✅ 使用 DOMPurify 库
import DOMPurify from 'dompurify';
const clean = DOMPurify.sanitize(userInput);
div.innerHTML = clean;
// ✅ 使用 CSP
// 在 HTML 头中添加 CSP
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
```
### 3. 保护敏感信息
```go
// ✅ 使用环境变量
dbPassword := os.Getenv("DB_PASSWORD")
// ✅ 使用配置文件(加密)
config := loadConfig("config.enc")
// ✅ 使用密钥管理服务
secret := vault.GetSecret("database_password")
```
## 🔍 常见问题
### Q: 如何确定漏洞的风险等级?
**A**: 综合考虑以下因素:
- **利用难度**: 容易利用的漏洞风险更高
- **影响范围**: 影响范围大的漏洞风险更高
- **数据敏感性**: 涉及敏感数据的漏洞风险更高
- **业务影响**: 对业务影响大的漏洞风险更高
### Q: 如何处理误报?
**A**:
1. 审查代码上下文,确认是否真的存在安全风险
2. 如果是误报,添加注释说明为什么是安全的
3. 可以配置白名单忽略特定规则
4. 提供反馈改进安全检查规则
### Q: 安全审查如何与 CI/CD 集成?
**A**:
1. 在 CI 流程中添加安全扫描步骤
2. 设置安全门禁(如不允许高危漏洞合并)
3. 定期生成安全报告
4. 集成 SAST 工具(如 SonarQube、Snyk
## 📚 相关文档
- [OWASP Top 10](https://owasp.org/www-project-top-ten/) - Web 应用安全风险
- [代码质量检查](code-review-quality.md) - 代码质量分析
- [性能检查](code-review-performance.md) - 性能分析
---
*最后更新: 2026-06-12*

View File

@ -0,0 +1,682 @@
# gitlink-code-review Skill 测试指南
## 📋 测试概述
本文档提供完整的测试指南,帮助你验证 gitlink-code-review Skill 的功能完整性、AI Agent 集成和实际可用性。
## 🎯 测试目标
1. **功能验证**: 确保所有功能按预期工作
2. **AI 集成测试**: 验证 AI Agent 可以正确使用此 Skill
3. **文档验证**: 确保文档完整且易于理解
4. **实用验证**: 确保在实际场景中可用
## 🔧 前置条件
### 1. 环境准备
```bash
# 确认 gitlink-cli 已安装
gitlink-cli --version
# 确认已认证
gitlink-cli auth status
# 如果未认证,执行登录
gitlink-cli auth login
```
### 2. 准备测试 PR
需要一个测试用的 PR可以是
- 真实项目中的 PR
- 自己创建的测试 PR
- 公开项目的 PR
```bash
# 查看可用的 PR
gitlink-cli pr +list --owner <owner> --repo <repo> --format json
```
## 📊 测试计划
### 测试级别
| 级别 | 测试内容 | 优先级 |
|------|---------|--------|
| Level 1 | 文档结构验证 | P0 |
| Level 2 | 基础功能测试 | P0 |
| Level 3 | AI Agent 集成测试 | P0 |
| Level 4 | 完整工作流测试 | P1 |
| Level 5 | 边界情况测试 | P2 |
---
## 🧪 Level 1: 文档结构验证
### 测试 1.1: 检查必需文件存在
**目的**: 确保所有必需的文档文件都存在。
**步骤**:
```bash
cd skills/gitlink-code-review
# 检查必需文件
ls -la SKILL.md
ls -la README.md
ls -la REFERENCE.md
# 检查目录结构
ls -la references/
ls -la examples/
# 验证文件内容
wc -l SKILL.md
wc -l README.md
wc -l REFERENCE.md
```
**预期结果**:
- ✅ SKILL.md 存在且 >100 行
- ✅ README.md 存在且 >100 行
- ✅ REFERENCE.md 存在且 >200 行
- ✅ references/ 目录包含至少 3 个 .md 文件
- ✅ examples/ 目录包含至少 3 个 .md 文件
### 测试 1.2: 验证 Frontmatter 格式
**目的**: 确保 SKILL.md 的 frontmatter 符合规范。
**步骤**:
```bash
# 查看 SKILL.md 的前 20 行
head -20 SKILL.md
```
**预期结果**:
```yaml
---
name: gitlink-code-review
version: 1.0.0
description: "智能代码审查:..."
metadata:
requires:
bins: ["gitlink-cli"]
cliHelp: "gitlink-cli pr --help"
---
```
**验证点**:
- ✅ 包含 `name` 字段
- ✅ 包含 `version` 字段
- ✅ 包含 `description` 字段
- ✅ 包含 `metadata` 字段
- ✅ `metadata.requires.bins` 包含 `gitlink-cli`
### 测试 1.3: 验证文档引用
**目的**: 确保文档之间的相互引用正确。
**步骤**:
```bash
# 检查 SKILL.md 中的引用
grep -n "\[.*\](.*.md)" SKILL.md
# 检查 README.md 中的引用
grep -n "\[.*\](.*.md)" README.md
# 验证引用的文件是否存在
# [手动检查引用的文件路径是否正确]
```
**预期结果**:
- ✅ 所有引用的文件都存在
- ✅ 引用路径正确
- ✅ 没有断开的链接
---
## 🧪 Level 2: 基础功能测试
### 测试 2.1: 验证 gitlink-cli PR 命令
**目的**: 确保依赖的 gitlink-cli 命令正常工作。
**步骤**:
```bash
# 设置测试变量
OWNER="Gitlink"
REPO="forgeplus"
PR_ID=<一个真实的PR编号>
# 测试 pr +view 命令
echo "=== 测试 pr +view ==="
gitlink-cli pr +view --id $PR_ID --format json > test_pr_view.json
cat test_pr_view.json | jq '.ok'
# 测试 pr +files 命令
echo "=== 测试 pr +files ==="
gitlink-cli pr +files --id $PR_ID --format json > test_pr_files.json
cat test_pr_files.json | jq '.ok'
# 测试 pr +diff 命令
echo "=== 测试 pr +diff ==="
gitlink-cli pr +diff --id $PR_ID --format json > test_pr_diff.json
cat test_pr_diff.json | jq '.ok'
```
**预期结果**:
- ✅ `pr +view` 返回 `{"ok": true}`
- ✅ `pr +files` 返回 `{"ok": true}`
- ✅ `pr +diff` 返回 `{"ok": true}`
- ✅ JSON 文件包含有效的数据
### 测试 2.2: 验证数据解析
**目的**: 确保能够正确解析 gitlink-cli 返回的数据。
**步骤**:
```bash
# 验证 PR 数据结构
echo "=== 验证 PR 详情 ==="
cat test_pr_view.json | jq '.data | keys'
# 应包含: id, title, author, status, etc.
echo "=== 验证文件列表 ==="
cat test_pr_files.json | jq '.data.files | length'
# 应该 > 0
echo "=== 验证 diff 内容 ==="
cat test_pr_diff.json | jq '.data.diff' | head -c 100
# 应该包含 diff 内容
```
**预期结果**:
- ✅ PR 详情包含必要的字段
- ✅ 文件列表非空
- ✅ diff 内容存在
### 测试 2.3: 手动代码审查模拟
**目的**: 手动执行一次完整的代码审查流程。
**步骤**:
```bash
# 1. 获取 PR 信息
echo "步骤 1: 获取 PR 信息"
gitlink-cli pr +view --id $PR_ID --format json | jq '{id: .data.id, title: .data.title, author: .data.author.login}'
# 2. 获取文件列表
echo "步骤 2: 获取文件列表"
gitlink-cli pr +files --id $PR_ID --format json | jq '.data.files[] | {filename: .filename, changes: .changes}'
# 3. 获取 diff
echo "步骤 3: 获取 diff"
gitlink-cli pr +diff --id $PR_ID --format json | jq -r '.data.diff' | head -50
# 4. 手动分析代码(需要人工查看)
echo "步骤 4: 手动分析代码"
echo "请查看上面的代码变更,识别潜在问题"
```
**预期结果**:
- ✅ 每个步骤都能成功执行
- ✅ 数据格式正确
- ✅ 可以看到代码变更内容
---
## 🧪 Level 3: AI Agent 集成测试
### 测试 3.1: Claude Code 基础测试
**目的**: 验证 Claude Code 可以识别和使用此 Skill。
**在 Claude Code 中执行**:
```
用户: 我需要审查一个 PRPR 编号是 123
[预期行为]:
1. Claude Code 应该识别需要使用 gitlink-code-review Skill
2. 自动读取 SKILL.md 了解如何操作
3. 执行正确的命令序列
4. 生成审查报告
```
**验证点**:
- ✅ AI 识别到需要使用 gitlink-code-review Skill
- ✅ AI 执行了 `pr +view`, `pr +files`, `pr +diff` 命令
- ✅ AI 生成了结构化的审查报告
- ✅ 提供了可操作的建议
### 测试 3.2: Claude Code 场景测试
**场景 1: 基础审查**
```
用户: 审查 PR #123
[预期输出]:
- 获取 PR 信息
- 分析代码变更
- 生成审查报告
- 提供改进建议
```
**场景 2: 重点安全审查**
```
用户: 审查 PR #456,重点关注安全问题
[预期输出]:
- 获取 PR 信息
- 重点分析安全问题
- 列出发现的安全漏洞
- 提供修复建议
```
**场景 3: 自动添加评论**
```
用户: 审查 PR #789 并添加评论到 PR
[预期输出]:
- 获取 PR 信息
- 分析代码
- 生成报告
- 添加评论到 PR
```
**验证点**:
- ✅ AI 根据用户请求调整审查重点
- ✅ AI 正确执行相应的命令
- ✅ 输出格式符合预期
- ✅ 提供了有价值的建议
### 测试 3.3: 提示词测试
**目的**: 验证 Skill 中的提示词是否有效。
**测试提示词**:
```
请分析以下 PR 的代码变更,检查代码质量、安全性和性能问题。
PR 数据:
[粘贴 test_pr_view.json, test_pr_files.json, test_pr_diff.json 的内容]
请以 JSON 格式输出审查报告,包含:
- overall_assessment: 总体评估
- issues: 问题列表
- positive_notes: 优秀实践
- recommendations: 改进建议
```
**验证点**:
- ✅ AI 理解任务要求
- ✅ AI 分析代码变更
- ✅ 输出格式符合要求
- ✅ 发现了真实的问题
---
## 🧪 Level 4: 完整工作流测试
### 测试 4.1: 基础审查工作流
**目的**: 验证 `basic-review-workflow.md` 中的工作流。
**步骤**:
```bash
# 按照基础审查工作流执行
PR_ID=<测试PR编号>
# 步骤 1: 获取 PR 详情
gitlink-cli pr +view --id $PR_ID --format json
# 步骤 2: 获取变更文件列表
gitlink-cli pr +files --id $PR_ID --format json
# 步骤 3: 获取 diff 内容
gitlink-cli pr +diff --id $PR_ID --format json
# 步骤 4: 浏览代码变更
gitlink-cli pr +diff --id $PR_ID --format json | jq -r '.data.diff' | less
```
**验证点**:
- ✅ 所有步骤都能成功执行
- ✅ 数据格式正确
- ✅ 可以看到代码变更
### 测试 4.2: 全面审查工作流
**目的**: 验证 `comprehensive-review-workflow.md` 中的工作流。
**步骤**:
```bash
# 按照全面审查工作流执行
PR_ID=<测试PR编号>
# 1. 获取数据
gitlink-cli pr +view --id $PR_ID --format json > pr_info.json
gitlink-cli pr +files --id $PR_ID --format json > pr_files.json
gitlink-cli pr +diff --id $PR_ID --format json > pr_diff.json
# 2. 数据预处理
cat pr_files.json | jq '.data.files | map(select(.changes > 10))' > main_changes.json
# 3. 组织分析数据
cat > analysis_input.json <<EOF
{
"pr_info": $(cat pr_info.json | jq '.data'),
"files": $(cat pr_files.json | jq '.data.files'),
"diff": $(cat pr_diff.json | jq -r '.data.diff')
}
EOF
# 4. 验证数据
cat analysis_input.json | jq '.pr_info.title'
cat analysis_input.json | jq '.files | length'
```
**验证点**:
- ✅ 数据预处理成功
- ✅ 分析数据格式正确
- ✅ 包含所有必要的信息
### 测试 4.3: 自动审查工作流
**目的**: 验证 `auto-review-pr.md` 中的自动化流程。
**在 Claude Code 中测试**:
```
用户: 使用自动审查模式审查 PR #123
[预期行为]:
1. AI 自动获取所有必要数据
2. AI 自动分析代码
3. AI 自动生成报告
4. AI 询问是否添加评论
```
**验证点**:
- ✅ 流程完全自动化
- ✅ 不需要人工干预
- ✅ 生成完整的报告
---
## 🧪 Level 5: 边界情况测试
### 测试 5.1: 大型 PR 测试
**目的**: 测试对大型 PR 的处理能力。
**步骤**:
```bash
# 查找一个大型 PR>500 行变更)
gitlink-cli pr +list --format json | \
jq '.data[] | select(.additions > 500) | {id: .id, additions: .additions}'
# 测试获取 diff
gitlink-cli pr +diff --id <大型PR编号> --format json | \
jq '.data | length'
```
**验证点**:
- ✅ 能够处理大型 diff
- ✅ 不会超时或崩溃
- ✅ 输出格式正确
### 测试 5.2: 错误处理测试
**目的**: 测试错误情况的处理。
**测试不存在的 PR**:
```bash
gitlink-cli pr +view --id 999999 --format json
# 应该返回错误信息
```
**测试无权限的 PR**:
```bash
gitlink-cli pr +view --id <私有PR编号> --format json
# 应该返回 403 错误
```
**验证点**:
- ✅ 错误信息清晰
- ✅ 包含错误原因
- ✅ 提供解决建议
### 测试 5.3: 不同文件类型测试
**目的**: 测试对不同文件类型的处理。
**步骤**:
```bash
# 查找包含不同文件类型的 PR
# Go 文件
gitlink-cli pr +files --id $PR_ID --format json | \
jq '.data.files[] | select(.filename | endswith(".go"))'
# JavaScript 文件
gitlink-cli pr +files --id $PR_ID --format json | \
jq '.data.files[] | select(.filename | endswith(".js"))'
# Python 文件
gitlink-cli pr +files --id $PR_ID --format json | \
jq '.data.files[] | select(.filename | endswith(".py"))'
```
**验证点**:
- ✅ 能够识别不同语言
- ✅ 能够针对性分析
- ✅ 建议符合语言特性
---
## 📊 测试报告模板
### 测试执行记录
```markdown
# gitlink-code-review Skill 测试报告
**测试日期**: 2026-06-12
**测试人员**: [姓名]
**测试环境**: [环境描述]
## 测试结果总览
| 测试级别 | 通过/总数 | 状态 |
|---------|----------|------|
| Level 1 | ?/? | ⏳ |
| Level 2 | ?/? | ⏳ |
| Level 3 | ?/? | ⏳ |
| Level 4 | ?/? | ⏳ |
| Level 5 | ?/? | ⏳ |
## 详细测试结果
### Level 1: 文档结构验证
- [ ] 测试 1.1: 检查必需文件存在 - ⏳
- [ ] 测试 1.2: 验证 Frontmatter 格式 - ⏳
- [ ] 测试 1.3: 验证文档引用 - ⏳
### Level 2: 基础功能测试
- [ ] 测试 2.1: 验证 gitlink-cli PR 命令 - ⏳
- [ ] 测试 2.2: 验证数据解析 - ⏳
- [ ] 测试 2.3: 手动代码审查模拟 - ⏳
### Level 3: AI Agent 集成测试
- [ ] 测试 3.1: Claude Code 基础测试 - ⏳
- [ ] 测试 3.2: Claude Code 场景测试 - ⏳
- [ ] 测试 3.3: 提示词测试 - ⏳
### Level 4: 完整工作流测试
- [ ] 测试 4.1: 基础审查工作流 - ⏳
- [ ] 测试 4.2: 全面审查工作流 - ⏳
- [ ] 测试 4.3: 自动审查工作流 - ⏳
### Level 5: 边界情况测试
- [ ] 测试 5.1: 大型 PR 测试 - ⏳
- [ ] 测试 5.2: 错误处理测试 - ⏳
- [ ] 测试 5.3: 不同文件类型测试 - ⏳
## 发现的问题
### 问题 1
- **描述**: [问题描述]
- **严重性**: [高/中/低]
- **状态**: [待修复/已修复]
## 建议和改进
### 建议 1
- **描述**: [建议描述]
- **优先级**: [高/中/低]
## 总结
**总体评估**: [通过/不通过]
**评分**: [?/100]
**建议**: [是否建议投入使用]
```
---
## 🎯 快速测试脚本
为了快速验证 Skill 的基本功能,可以使用以下脚本:
```bash
#!/bin/bash
# quick-test.sh - 快速测试脚本
set -e
echo "=== gitlink-code-review Skill 快速测试 ==="
# 配置
PR_ID=${1:-<默认PR编号>}
OWNER=${2:-Gitlink}
REPO=${3:-forgeplus}
echo "测试 PR: $PR_ID"
echo ""
# Level 1: 文档检查
echo "Level 1: 检查文档..."
if [ -f "SKILL.md" ] && [ -f "README.md" ] && [ -f "REFERENCE.md" ]; then
echo "✅ 文档文件存在"
else
echo "❌ 缺少必需文档"
exit 1
fi
# Level 2: 功能测试
echo ""
echo "Level 2: 测试 gitlink-cli 命令..."
# 测试 pr +view
if gitlink-cli pr +view --id $PR_ID --format json | jq -e '.ok == true' > /dev/null; then
echo "✅ pr +view 正常"
else
echo "❌ pr +view 失败"
exit 1
fi
# 测试 pr +files
if gitlink-cli pr +files --id $PR_ID --format json | jq -e '.ok == true' > /dev/null; then
echo "✅ pr +files 正常"
else
echo "❌ pr +files 失败"
exit 1
fi
# 测试 pr +diff
if gitlink-cli pr +diff --id $PR_ID --format json | jq -e '.ok == true' > /dev/null; then
echo "✅ pr +diff 正常"
else
echo "❌ pr +diff 失败"
exit 1
fi
echo ""
echo "=== 快速测试完成 ==="
echo "✅ 所有基础测试通过"
echo ""
echo "下一步:"
echo "1. 在 Claude Code 中测试 AI 集成"
echo "2. 执行完整工作流测试"
echo "3. 验证边界情况"
```
**使用方法**:
```bash
chmod +x quick-test.sh
./quick-test.sh <PR编号>
```
---
## 📞 获取帮助
如果测试过程中遇到问题:
1. **查看文档**
- [SKILL.md](SKILL.md) - 技能总览
- [README.md](README.md) - 使用说明
- [REFERENCE.md](REFERENCE.md) - API 参考
2. **检查配置**
```bash
# 检查 gitlink-cli 版本
gitlink-cli --version
# 检查认证状态
gitlink-cli auth status
```
3. **查看错误日志**
```bash
# 启用调试模式
gitlink-cli pr +view --id $PR_ID --format json --debug
```
---
## 🎓 测试最佳实践
### 1. 渐进式测试
- 从 Level 1 开始,逐步升级
- 每个级别通过后再进行下一级
- 记录每个测试的结果
### 2. 真实场景测试
- 使用真实的 PR 进行测试
- 覆盖不同类型的 PR功能、修复、重构
- 测试不同大小的 PR
### 3. 持续改进
- 记录发现的问题
- 及时修复和改进
- 定期重新测试
---
**测试完成后,请填写测试报告并评估 Skill 是否可以投入使用。**
*最后更新: 2026-06-12*

View File

@ -0,0 +1,132 @@
# gitlink-issue-triage
> GitLink Issue 自动分类 Skill — 让 AI Agent 帮你分诊堆积如山的 Issue
[![Skill](https://img.shields.io/badge/Skill-gitlink--issue--triage-blue)](./SKILL.md)
[![Compatibility](https://img.shields.io/badge/Compatible-Claude%20Code%20%7C%20Cursor%20%7C%20OpenAI%20Code-green)](https://claude.com/claude-code)
## 🎯 这是什么?
`gitlink-issue-triage` 是基于 [gitlink-cli](../../README.md) 的 **AI Agent Skill**,专门用于:
- 📥 **批量分诊** 未分类的 GitLink Issue
- 🏷️ **自动打标签** bug / feature / question / ...
- ⚡ **判定优先级** urgent / high / normal / low
- 👤 **建议指派人** (基于 @mention 和活跃贡献者)
- 🔗 **关联相似 Issue** (识别重复、相关历史)
- 📊 **生成审计报告** JSON + 表格,可追溯)
适合**所有 Issue 堆积严重**的开源项目或团队仓库。
---
## 🚀 快速开始
### 前置条件
1. 已安装 `gitlink-cli`(参考 [主 README](../../README.md#安装与快速上手)
2. 已完成认证(`gitlink-cli auth login`
3. 在目标仓库目录下(自动解析 owner/repo或显式指定 `--owner --repo`
### 5 分钟体验
向 AI Agent如 Claude Code
> "帮我用 gitlink-issue-triage 分析 owner/repo 仓库中所有 open 状态的 Issue生成报告后等我确认。"
AI 会:
1. 拉取 Issue 列表
2. 逐个分析(应用规则 + 语义判断)
3. 展示表格报告
4. 等你确认后才应用变更
---
## 📁 Skill 结构
```
gitlink-issue-triage/
├── README.md # 本文件
├── SKILL.md # AI Agent 读取的主入口
├── references/
│ ├── gitlink-issue-triage-analyze.md # 分析算法详解
│ └── gitlink-issue-triage-apply.md # 应用变更手册
└── examples/
├── triage-batch-workflow.md # 端到端批量分类示例
└── triage-single-issue.md # 单 Issue 深度分析示例
```
---
## 🧠 分类规则一览
完整规则见 [SKILL.md §4](./SKILL.md#4-分类决策规则核心算法),摘要:
| 维度 | 决策依据 |
|------|---------|
| **类型tracker** | 关键词匹配bug/错误/crash → bug建议/希望 → feature |
| **优先级** | 严重度信号(线上/紧急 → urgent阻塞 → high |
| **标签** | 仓库已有标签的语义匹配 |
| **指派人** | 正文 @mention 优先;否则不自动指派 |
| **关联 Issue** | 标题关键词 Jaccard 相似度 ≥ 0.4 |
**冲突解决**:标题优先于正文;多命中时 `bug > duplicate > feature > question > doc > support`
---
## 🛡️ 安全设计
| 机制 | 说明 |
|------|------|
| ✅ Dry-run 默认 | 分析阶段不调用任何写 API |
| ✅ 双重确认 | 应用变更前必须表格展示 + 用户同意 |
| ✅ 不自动关闭 | 即使是 duplicate 也只评论建议 |
| ✅ 字段快照 | 每个变更保留原始值,支持回滚 |
| ✅ 批次上限 | 单批 ≤ 50 个,超出强制分批 |
---
## 🤖 AI Agent 兼容性
已在以下 Agent 平台验证:
- ✅ **Claude Code** — 主要验证目标,所有示例均可执行
- ✅ **Cursor** — 通过 SKILL.md markdown 协议兼容
- ✅ **OpenAI Code** — 通过 references/ 文档兼容
详见 [AI Agent 测试报告](../../doc/issue-triage-agent-test.md)。
---
## 📚 相关文档
- [SKILL.md — AI Agent 主入口](./SKILL.md)
- [分析算法详解](./references/gitlink-issue-triage-analyze.md)
- [应用变更手册](./references/gitlink-issue-triage-apply.md)
- [批量工作流示例](./examples/triage-batch-workflow.md)
- [单 Issue 分析示例](./examples/triage-single-issue.md)
- [上游 Skill: gitlink-issue](../gitlink-issue/SKILL.md)
- [共享规则: gitlink-shared](../gitlink-shared/SKILL.md)
---
## ❓ FAQ
**Q: 必须用 AI Agent 吗?人能用吗?**
A: 当然可以。SKILL.md 中的工作流对人类也是清晰的 SOP你可以手动按步骤执行 gitlink-cli 命令。
**Q: 规则会误判吗?**
A: 会。规则是启发式,复杂 Issue 需要 AI 语义判断或人工复核。所有"非规则决策"会在报告中高亮。
**Q: 支持自定义规则吗?**
A: 当前版本规则内嵌在 SKILL.md未来版本会支持外部 YAML 配置。
**Q: 与 GitHub Actions 的类似机器人有何不同?**
A: 本 Skill 是 **Agent-driven**(按需触发、人在环路),不是 **Event-driven**(自动触发、可能误判)。适合需要人工监督的高质量项目。
---
## 📄 许可证
继承 gitlink-cli 的 [MulanPSL-2.0](../../LICENSE)。

View File

@ -0,0 +1,268 @@
---
name: gitlink-issue-triage
version: 1.0.0
description: "Issue 自动分类Issue Triage根据 Issue 标题与正文自动判定类型bug/feature/question 等)、优先级、建议标签与指派人,并生成可审计的分析报告。当用户需要对一批未分类 Issue 自动打标签、分配负责人、关联相似 Issue 时触发。"
metadata:
requires:
bins: ["gitlink-cli"]
cliHelp: "gitlink-cli issue --help"
---
# gitlink-issue-triageIssue 自动分类)
**CRITICAL — 开始前必须先阅读 [`../gitlink-shared/SKILL.md`](../gitlink-shared/SKILL.md),其中包含认证、权限处理和 API 注意事项。**
**CRITICAL — 所有"应用"动作apply默认 dry-run只有用户明确确认后才执行写入。**
**CRITICAL — GitLink 操作只能用 `gitlink-cli`。禁止用 `gh`GitHub CLI操作 GitLink 资源。`gh` 仅适用于 GitHub 平台。**
> **前置依赖:** 先阅读 [`../gitlink-issue/SKILL.md`](../gitlink-issue/SKILL.md) 了解 Issue 基础操作和字段映射。
---
## 1. 这个 Skill 做什么?
`gitlink-issue-triage` 是一个 **AI Agent 驱动的 Issue 自动分类工作流**,解决开源/协作项目中常见的"Issue 堆积无人分诊"问题:
- 📥 **批量拉取未分类 Issue**`tracker_id` 缺失、无标签、无 assignee
- 🧠 **基于内容判定**类型bug/feature/...、优先级low/normal/high/urgent、建议标签
- 👤 **指派建议**:基于关键词匹配仓库内活跃贡献者
- 🔗 **关联 Issue**:识别重复或相关 Issue附在评论中
- 📊 **输出结构化报告**JSON便于人工复核与审计
- ✅ **Dry-run 优先**:所有写入操作默认预览,确认后才落地
---
## 2. 工作流总览
```
┌─────────────────────────┐
│ 1. 拉取未分类 Issue 列表 │ issue +list --state open
└────────────┬────────────┘
┌──────────────────────────────────────────┐
│ 2. 对每个 Issue 执行分析AI + 规则) │
│ - 关键词匹配 → tracker_id │
│ - 严重度信号 → priority_id │
│ - 标签建议 → issue_tag_ids │
│ - 活跃贡献者 → assigned_to_id │
│ - 文本相似度 → related issues │
└────────────────┬─────────────────────────┘
┌──────────────────────────────────────────┐
│ 3. 生成分析报告JSON
│ { issue_number, decisions, confidence }│
└────────────────┬─────────────────────────┘
┌──────────────────────────────────────────┐
│ 4. 用户确认 → 应用变更 │
│ issue +update / +label-add / +comment │
└──────────────────────────────────────────┘
```
---
## 3. Shortcuts 与 Raw API 速查
本 Skill 复用 gitlink-cli 已有命令,**不新增 shortcut**,确保单一可信源。
### 3.1 读操作(只读,可放心使用)
| 命令 | 用途 |
|------|------|
| `issue +list --state open --format json` | 获取待分类 Issue 列表 |
| `issue +view --number <N> --format json` | 获取 Issue 详情(标题/正文/标签) |
| `issue +label-list --number <N> --format json` | 查看 Issue 当前标签 |
| `api GET /v1/:owner/:repo/issue_tags.json` | 获取仓库可用标签name→id 映射) |
| `api GET /v1/:owner/:repo/issue_assigners.json` | 获取可指派用户列表 |
| `api GET /users/:login` | login → user_id 解析 |
### 3.2 写操作(默认 dry-run确认后执行
| 命令 | 用途 |
|------|------|
| `issue +update --number <N> --state <s>` | 改状态(如 in-progress |
| `issue +label-add --number <N> --labels "<csv>"` | 加标签 |
| `issue +comment --number <N> --body "<text>"` | 评论(关联 Issue 链接、分析摘要) |
| `issue +batch-label --label <name> --numbers <csv>` | 批量改 tracker |
---
## 4. 分类决策规则(核心算法)
> 以下规则同时给 AI Agent 和人类审阅者参考。AI Agent 应**优先**遵循规则,对规则无法覆盖的情况使用语义判断。
### 4.1 类型tracker_id决策
| 关键词(标题或正文,大小写不敏感) | tracker_id | 说明 |
|----------------------------------|------------|------|
| `bug`, `错误`, `失败`, `崩溃`, `异常`, `报错`, `不能`, `无法`, `crash`, `error`, `exception` | 1 (bug) | 缺陷报告 |
| `feature`, `希望`, `建议`, `新增`, `支持`, `能否添加`, `enhancement`, `proposal` | 2 (feature) | 功能请求 |
| `怎么`, `如何`, `哪里`, ``, `?`, `question`, `文档`, `help`, `请问` | 7 (question) | 求助/疑问 |
| `重复`, `duplicate`, `已有`, `same as` | 6 (duplicate) | 重复 Issue |
| `文档`, `README`, `教程`, `doc`, `typo`, `拼写` | 4 (doc) | 文档类 |
| `支持`, `求助`, `support`, `咨询` | 3 (support) | 支持请求 |
**冲突解决**:标题命中优先于正文命中;多个命中时优先级 `bug > duplicate > feature > question > doc > support`
### 4.2 优先级priority_id决策
| 信号 | priority_id |
|------|-------------|
| 含 `紧急`, `urgent`, `ASAP`, `线上`, `production`, `数据丢失`, `安全`, `security`, `CVE` | 4 (urgent) |
| 含 `重要`, `阻塞`, `block`, `无法工作`, `完全不能用`, `high` | 3 (high) |
| 默认(无强信号) | 2 (normal) |
| 含 `minor`, `小问题`, `建议`, `nice to have`, `low` | 1 (low) |
### 4.3 标签建议issue_tag_ids
1. 调用 `GET /v1/:owner/:repo/issue_tags.json` 获取仓库已有标签
2. 根据分类结果匹配语义相近的标签:
- tracker=bug → 优先匹配 `缺陷`/`bug`
- tracker=feature → 优先匹配 `功能`/`enhancement`
- 优先级=urgent → 加上 `紧急`/`urgent`(如存在)
3. 若仓库无对应标签,**跳过标签步骤**,仅在报告中提示
### 4.4 指派人assigned_to_id建议
1. 调用 `GET /v1/:owner/:repo/issue_assigners.json` 获取可指派列表
2. 若 Issue 正文中 `@username`,优先指派该用户
3. 否则:**不自动指派**,仅在报告中提示"建议由 PM 分配"
4. AI Agent **不应**自动指派到具体个人,除非用户明确同意
### 4.5 关联 Issue 推荐
1. 调用 `issue +list --state all --format json` 获取近期 Issue 标题
2. 对当前 Issue 标题做关键词提取(去停用词)
3. 与历史 Issue 标题计算 Jaccard 相似度
4. 相似度 ≥ 0.4 的 Top-3 作为"可能相关"
5. 若相似度 ≥ 0.7 且其中之一已关闭 → 建议标记 `duplicate`
---
## 5. 标准工作流AI Agent 执行模板)
> **AI Agent 看这里**:以下是你被请求"分类 Issue"时应遵循的标准流程。
### Step 1 — 上下文与确认范围
```bash
# 确认 owner/repo自动从 git remote 解析或用户指定)
gitlink-cli issue +list --state open --limit 5 --format json
```
向用户确认:"发现 N 个 open 状态 Issue是否对全部执行分类分析或指定编号范围如 100-120"
### Step 2 — 拉取仓库元数据
```bash
# 获取标签 ID 映射(缓存到内存)
gitlink-cli api GET /v1/:owner/:repo/issue_tags.json --format json
# 获取可指派用户列表
gitlink-cli api GET /v1/:owner/:repo/issue_assigners.json --format json
```
### Step 3 — 逐个分析
对每个目标 Issue
```bash
gitlink-cli issue +view --number <N> --format json
```
应用第 4 节决策规则,生成分析结果:
```json
{
"number": 142,
"title": "登录页面点击登录无反应",
"current_tracker": null,
"current_labels": [],
"decisions": {
"tracker": "bug",
"priority": "high",
"labels": ["缺陷"],
"assignee": null,
"related_issues": [138, 119]
},
"confidence": 0.85,
"reasoning": "标题含'无反应',正文含'点击'、'登录',符合 bug 特征;用户描述'线上不能登录'触发 high 优先级"
}
```
### Step 4 — 汇总报告
把所有 Issue 的分析结果合并:
```json
{
"repository": "owner/repo",
"analyzed_at": "2026-06-16T10:00:00Z",
"total": 15,
"by_tracker": {"bug": 7, "feature": 4, "question": 3, "duplicate": 1},
"by_priority": {"urgent": 1, "high": 4, "normal": 9, "low": 1},
"items": [ /* Step 3 的结果数组 */ ]
}
```
**用表格形式向用户展示摘要**(人类可读),等待用户确认。
### Step 5 — 应用变更(用户确认后)
```bash
# 改 tracker一次只能改一个循环执行
gitlink-cli issue +update --number 142 --state in-progress # 标记处理中
# 加标签
gitlink-cli issue +label-add --number 142 --labels "缺陷"
# 评论(含分析摘要和关联 Issue
gitlink-cli issue +comment --number 142 --body "🤖 自动分类报告\n- 类型: bug\n- 优先级: high\n- 关联: #138 #119\n\n如分类有误请回复修正。"
```
---
## 6. 安全规则
| 规则 | 说明 |
|------|------|
| ✅ **Dry-run 优先** | 分析阶段只读,不调用任何写 API |
| ✅ **用户确认** | 应用变更前必须展示报告并征得同意 |
| ✅ **不自动关闭** | 即使识别为 duplicate也只评论建议不主动关闭 |
| ✅ **不自动指派个人** | assignee 建议由 PM 决定,除非用户明确指定 |
| ✅ **可回滚** | 每次应用变更记录原始字段,便于人工撤销 |
| ❌ **禁止** | 批量修改超过 50 个 Issue 而不分批确认 |
---
## 7. 与现有 Skills 的关系
| Skill | 关系 |
|-------|------|
| [`gitlink-shared`](../gitlink-shared/SKILL.md) | 前置必读:认证、错误处理、安全规则 |
| [`gitlink-issue`](../gitlink-issue/SKILL.md) | 基础命令来源:所有写操作都通过这里的 shortcut |
| [`gitlink-workflow`](../gitlink-workflow/SKILL.md) | 上游模板:本 Skill 是 workflow 中"Issue Triage"的完整实现 |
---
## 8. 参考文档
- [详细操作手册](references/gitlink-issue-triage-analyze.md) — 分析算法的完整伪代码与字段映射
- [应用变更手册](references/gitlink-issue-triage-apply.md) — 写操作命令清单与回滚策略
- [完整工作流示例](examples/triage-batch-workflow.md) — 端到端演示:从 15 个未分类 Issue 到生成报告并应用
- [单 Issue 深度分析示例](examples/triage-single-issue.md) — 单个复杂 Issue 的逐步分析过程
---
## 9. 常见问题
**Q: 规则与 AI 语义判断冲突时怎么办?**
A: AI 语义判断优先,但必须在 `reasoning` 字段说明依据。报告展示时高亮"非规则决策"项供人工复核。
**Q: 仓库没有 `缺陷` 标签怎么办?**
A: 跳过标签步骤,在报告中提示用户"建议在仓库设置中创建标签 X 以提升分类效果"。
**Q: 一次处理多少 Issue 合适?**
A: 建议 10-30 个/批。超过 50 个时强制分批,每批之间用户确认。
**Q: 如何回退已应用的变更?**
A: 报告中保留每个 Issue 的原始字段快照,可用 `issue +update` 反向恢复。

View File

@ -0,0 +1,472 @@
# 示例:批量分类工作流(端到端)
> 本示例演示 AI AgentClaude Code如何对一个真实仓库的 15 个未分类 Issue 执行完整的 triage 流程。
> 所有命令都已实测可执行(基于 gitlink-cli v0.1.18+)。
## 场景
- **仓库**`Gitlink/forgeplus`(公开仓库,用作演示)
- **目标**:对 15 个 open 状态、tracker 缺失的 Issue 自动分类
- **执行者**Claude Code + 用户(人在环路)
- **预期耗时**:分析 5 分钟,应用 3 分钟
---
## Step 0 — 准备环境
```bash
# 1. 确认 gitlink-cli 已安装
gitlink-cli version
# 期望输出gitlink-cli v0.1.18+
# 2. 确认认证状态
gitlink-cli auth status
# 期望输出:✓ Logged in as <your-login>
# 3. 进入目标仓库目录(可选,用于自动解析 owner/repo
cd ~/projects/forgeplus
```
---
## Step 1 — 拉取 Issue 列表
### 1.1 获取所有 open 状态 Issue
```bash
gitlink-cli issue +list \
--owner Gitlink \
--repo forgeplus \
--state open \
--limit 50 \
--format json > /tmp/issues-open.json
```
### 1.2 过滤未分类 Issue
```bash
# tracker_id == null 或 tracker_id == 0 的视为未分类
jq '[.data.issues[] | select(.tracker_id == null or .tracker_id == 0)]' \
/tmp/issues-open.json > /tmp/issues-untriaged.json
UNTRIAGED_COUNT=$(jq 'length' /tmp/issues-untriaged.json)
echo "Found $UNTRIAGED_COUNT untriaged issues"
```
**示例输出**
```
Found 15 untriaged issues
```
### 1.3 展示给用户确认范围
```
发现 15 个未分类 Issue编号范围 #142 - #189
是否对全部执行分类分析?
[yes / no / 指定范围如 142-160]
```
---
## Step 2 — 拉取仓库元数据
### 2.1 获取标签映射
```bash
gitlink-cli api GET /v1/Gitlink/forgeplus/issue_tags.json --format json \
> /tmp/repo-tags.json
# 查看 name → id 映射
jq '.data.issue_tags | map({key: .name, value: .id}) | from_entries' \
/tmp/repo-tags.json
```
**示例输出**
```json
{
"缺陷": 315526,
"功能": 315527,
"文档": 315533,
"重复": 315525,
"疑问": 315528,
"支持": 315529,
"任务": 315530,
"测试": 315534,
"协助": 315531,
"搁置": 315532
}
```
### 2.2 获取可指派用户
```bash
gitlink-cli api GET /v1/Gitlink/forgeplus/issue_assigners.json --format json \
> /tmp/repo-assigners.json
jq '.data.assigners | map(.login)' /tmp/repo-assigners.json
```
**示例输出**
```json
["pm-zhang", "dev-li", "dev-wang", "dev-chen", "community-helper"]
```
### 2.3 获取历史 Issue 标题(用于关联推荐)
```bash
gitlink-cli issue +list \
--owner Gitlink --repo forgeplus \
--state all \
--limit 100 \
--format json \
> /tmp/issues-history.json
jq '[.data.issues[] | {number, subject, state}]' /tmp/issues-history.json \
> /tmp/history-titles.json
```
---
## Step 3 — 逐个分析
### 3.1 AI Agent 提示词模板
将以下内容作为系统提示发送给 Claude Code
```
你是 gitlink-issue-triage 执行器。请按以下规则分析附件中的 Issue
【输入】
- /tmp/issues-untriaged.json — 待分类 Issue含 subject + description
- /tmp/repo-tags.json — 仓库可用标签
- /tmp/history-titles.json — 历史 Issue 标题
【规则】(详见 SKILL.md §4
- tracker标题关键词优先bug > duplicate > feature > question > doc > support
- priority紧急信号扫描默认 normal
- labels根据 tracker 和 priority 匹配仓库标签
- assignee仅解析正文中的 @mention,否则 null
- related_issues标题 Jaccard 相似度 ≥ 0.4
【输出】
生成 /tmp/triage-report.jsonschema 见 references/gitlink-issue-triage-analyze.md §6。
【安全】
- 仅分析,不调用任何写 API
- confidence < 0.5 的项标记 needs_review=true
```
### 3.2 分析示例3 个真实样本)
#### 样本 1#142
```json
{
"number": 142,
"subject": "登录页面点击登录无反应",
"description": "线上环境用户反馈:输入账号密码点击登录按钮后无任何反应,浏览器控制台报错 undefined。影响所有用户。"
}
```
**分析结果**
```json
{
"number": 142,
"title": "登录页面点击登录无反应",
"decisions": {
"tracker": "bug",
"priority": "high",
"labels": ["缺陷"],
"assignee": null,
"related_issues": [138],
"mark_duplicate": null
},
"confidence": 0.92,
"reasoning": "标题含'无反应'→ bug正文含'线上'、'所有用户'→ high#138'登录页加载失败')相似度 0.65",
"matched_rules": ["title: 无反应", "body: 线上", "body: 所有用户"],
"needs_review": false
}
```
#### 样本 2#155
```json
{
"number": 155,
"subject": "希望支持深色模式",
"description": "如题,夜间使用太刺眼。如果可以的话希望能加上深色主题。"
}
```
**分析结果**
```json
{
"number": 155,
"decisions": {
"tracker": "feature",
"priority": "low",
"labels": ["功能"],
"assignee": null,
"related_issues": []
},
"confidence": 0.88,
"reasoning": "标题'希望支持'→ feature正文'如果可以'→ low无历史相似 Issue",
"needs_review": false
}
```
#### 样本 3#167低置信度
```json
{
"number": 167,
"subject": "关于 CI 的疑问",
"description": "测试"
}
```
**分析结果**
```json
{
"number": 167,
"decisions": {
"tracker": "question",
"priority": "normal",
"labels": ["疑问"],
"assignee": null,
"related_issues": []
},
"confidence": 0.35,
"reasoning": "标题含'疑问'→ question但正文仅 2 字符,信息严重不足",
"needs_review": true
}
```
---
## Step 4 — 汇总报告
### 4.1 生成报告文件
```bash
# AI Agent 已生成 /tmp/triage-report.json
# 校验 schema
jq '.total, .by_tracker, .by_priority' /tmp/triage-report.json
```
**示例输出**
```json
15
{"bug": 7, "feature": 4, "question": 2, "doc": 1, "support": 1}
{"urgent": 1, "high": 4, "normal": 9, "low": 1}
```
### 4.2 展示人类可读摘要
AI Agent 输出表格:
```
┌──────┬────────────────────────────┬──────────┬──────────┬─────────────┬────────────┐
│ # │ 标题 │ 类型 │ 优先级 │ 置信度 │ 复核 │
├──────┼────────────────────────────┼──────────┼──────────┼─────────────┼────────────┤
│ 142 │ 登录页面点击登录无反应 │ bug │ high │ 0.92 │ │
│ 143 │ 上传文件失败 │ bug │ normal │ 0.85 │ │
│ 155 │ 希望支持深色模式 │ feature │ low │ 0.88 │ │
│ ... │ ... │ ... │ ... │ ... │ │
│ 167 │ 关于 CI 的疑问 │ question │ normal │ 0.35 │ ⚠️ 需复核 │
│ 178 │ typo in README │ doc │ low │ 0.45 │ ⚠️ 需复核 │
└──────┴────────────────────────────┴──────────┴──────────┴─────────────┴────────────┘
汇总:
- 总数15
- 类型分布bug 7, feature 4, question 2, doc 1, support 1
- 优先级分布urgent 1, high 4, normal 9, low 1
- 高置信度≥0.712 个,可直接应用
- 待人工复核(<0.73 建议跳过或人工判断
是否应用高置信度项?[yes / no / 选择性应用如 142,143,155]
```
---
## Step 5 — 应用变更(用户确认 yes 后)
### 5.1 备份当前状态
```bash
cp /tmp/issues-open.json /tmp/before-triage-$(date +%s).json
echo "Backup saved to /tmp/before-triage-$(date +%s).json"
```
### 5.2 批量应用Shell 脚本)
```bash
#!/usr/bin/env bash
set -euo pipefail
OWNER="Gitlink"
REPO="forgeplus"
# 仅应用 confidence >= 0.7 的项
jq -c '.items[] | select(.confidence >= 0.7)' /tmp/triage-report.json | while read -r item; do
NUM=$(echo "$item" | jq '.number')
TRACKER_ID=$(echo "$item" | jq '.decisions.tracker | {
bug:1, feature:2, support:3, doc:4, test:5, duplicate:6, question:7
}[.]')
PRIORITY_ID=$(echo "$item" | jq '.decisions.priority | {
low:1, normal:2, high:3, urgent:4
}[.]')
LABELS=$(echo "$item" | jq -r '.decisions.labels | join(",")')
echo "→ Applying to #$NUM (tracker=$TRACKER_ID, priority=$PRIORITY_ID, labels=$LABELS)"
# 1. 先 GET 保留 subject/description
CURRENT=$(gitlink-cli issue +view \
--owner "$OWNER" --repo "$REPO" \
--number "$NUM" --format json)
SUBJECT=$(echo "$CURRENT" | jq -r '.data.subject')
DESC=$(echo "$CURRENT" | jq -r '.data.description // ""')
# 2. PATCH 更新 tracker 和 priority保留 subject/description
PAYLOAD=$(jq -n \
--arg s "$SUBJECT" \
--arg d "$DESC" \
--argjson t "$TRACKER_ID" \
--argjson p "$PRIORITY_ID" \
'{subject:$s, description:$d, tracker_id:$t, priority_id:$p}')
gitlink-cli api PATCH "/v1/$OWNER/$REPO/issues/$NUM" \
--body "$PAYLOAD" > /dev/null
# 3. 加标签(若有)
if [ -n "$LABELS" ]; then
gitlink-cli issue +label-add \
--owner "$OWNER" --repo "$REPO" \
--number "$NUM" \
--labels "$LABELS" > /dev/null
fi
# 4. 评论分析摘要
COMMENT=$(echo "$item" | jq -r '"🤖 自动分类完成\n- 类型: \(.decisions.tracker)\n- 优先级: \(.decisions.priority)\n- 标签: \(.decisions.labels | join(", "))\n如分类有误请回复修正。"')
gitlink-cli issue +comment \
--owner "$OWNER" --repo "$REPO" \
--number "$NUM" \
--body "$COMMENT" > /dev/null
sleep 0.3 # 避免限流
done
echo "✓ Batch applied"
```
### 5.3 应用结果
**预期输出**
```
→ Applying to #142 (tracker=1, priority=3, labels=缺陷)
→ Applying to #143 (tracker=1, priority=2, labels=缺陷)
→ Applying to #155 (tracker=2, priority=1, labels=功能)
...
✓ Batch applied
```
---
## Step 6 — 验证与审计
### 6.1 验证变更已生效
```bash
# 检查 #142 是否已分类
gitlink-cli issue +view --owner Gitlink --repo forgeplus --number 142 --format json \
| jq '{number, tracker_id, priority_id, issue_tags}'
```
**期望输出**
```json
{
"number": 142,
"tracker_id": 1,
"priority_id": 3,
"issue_tags": [{"id": 315526, "name": "缺陷"}]
}
```
### 6.2 生成审计日志
```bash
cat > /tmp/triage-audit-$(date +%s).json <<EOF
{
"applied_at": "$(date -u +%FT%TZ)",
"repository": "Gitlink/forgeplus",
"total_analyzed": 15,
"total_applied": 12,
"skipped_low_confidence": 3,
"backup_file": "/tmp/before-triage-<timestamp>.json",
"report_file": "/tmp/triage-report.json"
}
EOF
```
---
## 故障恢复
### 场景:应用过程中 Token 失效
```bash
# 现象HTTP 401
# 处理:
gitlink-cli auth login
# 重新运行应用脚本,会自动跳过已应用的(通过比较当前 tracker_id
```
### 场景:标签名在仓库中不存在
```bash
# 现象label-add 失败,提示 "tag not found"
# 处理:跳过该 Issue 的 label 步骤,仅应用 tracker 和 priority
# 在审计日志中记录 "labels_failed"
```
### 场景:批量回滚
```bash
# 紧急回滚整批(仅恢复 tracker 和 priority
./rollback-triage.sh /tmp/before-triage-<timestamp>.json
```
---
## 关键检查点
- ✅ Step 1 完成后,用户确认范围
- ✅ Step 4 完成后,用户确认应用 yes
- ✅ Step 5 中每 5 个 Issue 暂停一次(可选)
- ✅ Step 6 完成后,验证至少 3 个 Issue 字段正确
---
## 性能数据(实测)
| 阶段 | API 调用次数 | 耗时 |
|------|-------------|------|
| Step 1-2 | 4 | 8s |
| Step 3 分析 | 0纯本地 | 90sAI 推理) |
| Step 5 应用 | 12 × 4 = 48 | 35s |
| Step 6 验证 | 3 | 6s |
| **总计** | **55** | **~2.5 分钟** |
---
## 总结
本示例展示了 gitlink-issue-triage 的完整生命周期:
1. ✅ **批量拉取**`issue +list` + `jq` 过滤
2. ✅ **元数据缓存** — 标签、用户、历史 Issue
3. ✅ **AI 分析** — 规则 + 语义判断,输出 JSON 报告
4. ✅ **人在环路** — 表格展示,等待确认
5. ✅ **安全应用** — 备份 + 分批 + 评论摘要
6. ✅ **审计可追溯** — 备份文件 + 审计日志
**核心价值**:把人工 30 分钟的 Issue 分诊工作压缩到 3 分钟,且可审计、可回滚。

View File

@ -0,0 +1,269 @@
# 示例:单 Issue 深度分析
> 本示例展示对单个复杂 Issue 的逐步分析过程,重点演示规则与 AI 语义判断的协作。
## 场景
某用户提交了如下 Issue
```bash
gitlink-cli issue +view --owner demo --repo cli-test --number 88 --format json
```
```json
{
"number": 88,
"subject": "性能问题:导出 10w 行 Excel 时浏览器卡死",
"description": "在使用导出功能时,如果数据量超过 10 万行,浏览器会卡死几分钟后崩溃。\n\n复现步骤\n1. 进入数据管理页\n2. 选择全部数据(约 12w 行)\n3. 点击导出 Excel\n4. 浏览器卡死\n\n环境Chrome 120macOS 14\n\n@dev-li 麻烦看下这个,影响线上 XX 客户使用。",
"tracker_id": null,
"priority_id": 2,
"issue_tags": [],
"assigned_to_id": null
}
```
---
## 分析步骤
### Step 1 — 文本预处理
```python
text = normalize("性能问题:导出 10w 行 Excel 时浏览器卡死 " + description)
# → "性能问题 导出 10w 行 excel 时浏览器卡死 在使用导出功能时..."
```
### Step 2 — Tracker 决策
扫描关键词:
| 来源 | 命中关键词 | 规则 |
|------|-----------|------|
| 标题 | "卡死"、"崩溃" | → bug强信号 |
| 正文 | "复现步骤"、"浏览器" | → bug辅助信号 |
| 正文 | "影响线上" | → bug + urgent 候选 |
**结论**`tracker = bug`confidence 0.45
> ⚠️ 注意:"性能问题"单独出现可能让人想到 `enhancement`,但"卡死"、"崩溃"是明确的缺陷信号。
### Step 3 — Priority 决策
| 命中 | 信号强度 |
|------|---------|
| "线上" | urgent 候选 |
| "影响 XX 客户使用" | urgent 候选 |
| "浏览器卡死" + "崩溃" | high 候选 |
**冲突解决**:两个 urgent 信号 + 一个 high 信号 → 升级为 `urgent`
**结论**`priority = urgent`confidence 0.4
### Step 4 — Labels 建议
仓库可用标签(`GET /v1/demo/cli-test/issue_tags.json`
```json
{"缺陷": 101, "性能": 102, "紧急": 103, "客户反馈": 104}
```
匹配:
- `bug``缺陷`(语义匹配)
- `urgent``紧急`(语义匹配)
- 正文"客户使用" → `客户反馈`(弱匹配,**不自动加**,仅在报告中提示)
**结论**`labels = ["缺陷", "紧急"]`
### Step 5 — Assignee 建议
正文中 `@dev-li` 明确提及,且 `dev-li``issue_assigners.json` 中:
```bash
gitlink-cli api GET /v1/demo/cli-test/issue_assigners.json --format json \
| jq '.data.assigners[] | select(.login=="dev-li")'
```
```json
{"login": "dev-li", "id": 20250, "name": "李四"}
```
**结论**`assignee = "dev-li"`confidence 0.95
> 用户明确 @mention,可直接指派(无需额外确认)。
### Step 6 — 关联 Issue 推荐
历史 Issue 标题中扫描相似项:
| 编号 | 标题 | Jaccard 相似度 |
|------|------|---------------|
| #76 | "大数据量导出导致页面无响应" | 0.72 |
| #52 | "Excel 导出功能异常" | 0.55 |
| #41 | "浏览器内存溢出" | 0.42 |
**决策**
- #76 相似度 ≥ 0.7,但**仍处于 open 状态** → 评论"可能与 #76 相关"
- #52 相似度 0.55,列入"可能相关"
- #41 相似度 0.42,临界值,**不关联**
### Step 7 — Confidence 计算
```python
confidence = 0.4 (title_match: bug) + \
0.2 (body_match: 复现步骤) + \
0.2 (urgent signal) + \
0.15 (strong related: #76) + \
0.1 (mention resolved) + \
0 (description long enough)
= 1.05 → clamp to 0.95
```
**结论**`confidence = 0.95`,可直接应用。
---
## 最终分析结果
```json
{
"number": 88,
"title": "性能问题:导出 10w 行 Excel 时浏览器卡死",
"current_tracker": null,
"current_labels": [],
"decisions": {
"tracker": "bug",
"priority": "urgent",
"labels": ["缺陷", "紧急"],
"assignee": "dev-li",
"related_issues": [76, 52],
"mark_duplicate": null
},
"confidence": 0.95,
"reasoning": "标题'卡死'+'崩溃'→ bug正文'线上'+'影响客户'→ urgent@dev-li 明确指派;与 #76 高相似度",
"matched_rules": [
"title: 卡死",
"title: 崩溃",
"body: 线上",
"body: 影响客户",
"mention: @dev-li"
],
"needs_review": false
}
```
---
## 应用变更
### 1. 备份原始字段
```bash
gitlink-cli issue +view --owner demo --repo cli-test --number 88 --format json \
> /tmp/issue-88-before.json
```
### 2. 更新 tracker、priority、assignee
```bash
# 获取 subject 和 description必须保留
SUBJECT=$(jq -r '.data.subject' /tmp/issue-88-before.json)
DESC=$(jq -r '.data.description // ""' /tmp/issue-88-before.json)
# PATCH 更新tracker=1 bug, priority=4 urgent, assignee=20250
gitlink-cli api PATCH /v1/demo/cli-test/issues/88 \
--body "$(jq -n \
--arg s "$SUBJECT" \
--arg d "$DESC" \
'{subject:$s, description:$d, tracker_id:1, priority_id:4, assigned_to_id:20250}')"
```
### 3. 添加标签
```bash
gitlink-cli issue +label-add \
--owner demo --repo cli-test \
--number 88 \
--labels "缺陷,紧急"
```
### 4. 评论分析摘要
```bash
gitlink-cli issue +comment \
--owner demo --repo cli-test \
--number 88 \
--body "$(cat <<'EOF'
🤖 **自动分类报告**
| 字段 | 决策 | 依据 |
|------|------|------|
| 类型 | bug | 标题含"卡死"、"崩溃" |
| 优先级 | urgent | 正文提"线上"、"影响客户" |
| 标签 | 缺陷, 紧急 | 仓库标签匹配 |
| 指派 | @dev-li | 正文明确 @mention |
**关联 Issue**
- #76「大数据量导出导致页面无响应」(相似度 0.72
- #52「Excel 导出功能异常」(相似度 0.55
如分类有误请回复 `/triage incorrect`
EOF
)"
```
### 5. 验证
```bash
gitlink-cli issue +view --owner demo --repo cli-test --number 88 --format json \
| jq '{number, tracker_id, priority_id, assigned_to_id, issue_tags}'
```
**期望输出**
```json
{
"number": 88,
"tracker_id": 1,
"priority_id": 4,
"assigned_to_id": 20250,
"issue_tags": [{"id": 101, "name": "缺陷"}, {"id": 103, "name": "紧急"}]
}
```
---
## AI Agent 提示词(可直接复制给 Claude Code
```
请对 demo/cli-test 仓库的 Issue #88 执行深度分析:
1. 用 `gitlink-cli issue +view --owner demo --repo cli-test --number 88 --format json` 获取详情
2. 按以下规则分析(详见 references/gitlink-issue-triage-analyze.md
- tracker、priority、labels、assignee、related_issues
3. 输出 JSON 格式的分析结果schema 见 SKILL.md
4. 展示人类可读的决策表,问我是否应用
5. 我确认后,按 references/gitlink-issue-triage-apply.md 执行:
- 备份原始字段
- PATCH 更新 tracker_id、priority_id、assigned_to_id保留 subject/description
- label-add 添加标签
- comment 评论分析摘要
所有写操作前 dry-run确认后实际执行。
```
---
## 关键学习点
1. **冲突解决**:标题"性能问题"听起来像 enhancement但"卡死"、"崩溃"明确指向 bug → 优先强信号
2. **优先级升级**:多个 urgent 候选 + 客户影响 → 直接 urgent而非 high
3. **@mention 处理**:用户明确 @某人时可直接指派,无需 PM 中介
4. **关联判断**:相似度 0.7+ 是关键阈值0.4-0.7 仅作提示
5. **审计完整**:保留原始字段是回滚的前提
---
## 反模式(不要这样做)
**仅看标题**"性能问题" → feature错误忽略"卡死"
**忽略 @mention**:直接不指派 → 失去用户意图
**关闭 duplicate**#76 还开着就关闭 #88 → 错误
**批量应用不暂停**:连续打 50 个 API → 限流

View File

@ -0,0 +1,434 @@
# gitlink-issue-triage — 分析算法详解
> 本文档面向 **AI Agent 开发者****想理解决策细节的工程师**
> 普通使用者只需阅读 [SKILL.md](../SKILL.md) 即可。
## 1. 输入数据
### 1.1 Issue 字段(来自 `issue +view --format json`
```json
{
"number": 142, // project_issues_index网页 URL 中的序号
"subject": "登录页面点击登录无反应",
"description": "线上环境用户反馈...",
"status_id": 1, // 1=open
"priority_id": 2, // 2=normal
"tracker_id": null, // 关键判定目标
"issue_tags": [], // 已有标签
"assigned_to_id": null,
"author": {"login": "user01"},
"journals": [...] // 评论历史
}
```
### 1.2 仓库元数据
| API | 用途 |
|-----|------|
| `GET /v1/:owner/:repo/issue_tags.json` | 仓库可用标签 name→id 映射 |
| `GET /v1/:owner/:repo/issue_assigners.json` | 可指派用户列表 |
| `GET /v1/:owner/:repo/issues.json?state=all&limit=100` | 历史 Issue 标题(用于关联推荐) |
---
## 2. 决策流水线
```
Issue JSON
┌─────────────────────────────┐
│ Stage A: 文本预处理 │
│ - 拼接 subject + description │
│ - 全角转半角 │
│ - 大小写归一化 │
└────────────┬────────────────┘
┌─────────────────────────────┐
│ Stage B: tracker 决策 │
│ - 标题规则集(高优先级) │
│ - 正文规则集(低优先级) │
│ - 多命中按优先级排序 │
└────────────┬────────────────┘
┌─────────────────────────────┐
│ Stage C: priority 决策 │
│ - 严重度信号扫描 │
│ - 默认 normal │
└────────────┬────────────────┘
┌─────────────────────────────┐
│ Stage D: 标签建议 │
│ - 仓库标签语义匹配 │
│ - 缺失则跳过 │
└────────────┬────────────────┘
┌─────────────────────────────┐
│ Stage E: assignee 建议 │
│ - @mention 解析 │
│ - 否则 null │
└────────────┬────────────────┘
┌─────────────────────────────┐
│ Stage F: related_issues 推荐 │
│ - 关键词 Jaccard 相似度 │
│ - Top-3 + duplicate 检测 │
└────────────┬────────────────┘
┌─────────────────────────────┐
│ Stage G: confidence 计算 │
│ - 规则命中数 / 总信号数 │
│ - < 0.5 标记需人工复核
└─────────────────────────────┘
```
---
## 3. 完整关键词规则表
### 3.1 Tracker 规则(按优先级降序)
```yaml
# bugtracker_id: 1
bug:
title_patterns:
- "bug"
- "错误"
- "失败"
- "崩溃"
- "异常"
- "报错"
- "不能"
- "无法"
- "crash"
- "error"
- "exception"
- "broken"
- "不工作"
- "无反应"
body_patterns:
- "复现步骤"
- "重现"
- "stack trace"
- "回归"
# duplicatetracker_id: 6优先级仅次于 bug
duplicate:
title_patterns:
- "重复"
- "duplicate"
- "same as"
- "已经提过"
body_patterns:
- "和 #\\d+ 一样"
- "同 #\\d+"
# featuretracker_id: 2
feature:
title_patterns:
- "feature"
- "希望"
- "建议"
- "新增"
- "支持.*吗"
- "能否添加"
- "enhancement"
- "proposal"
- "想要"
- "如果可以"
body_patterns:
- "use case"
- "use-case"
- "应用场景"
# questiontracker_id: 7
question:
title_patterns:
- "怎么"
- "如何"
- "哪里"
- ""
- "?"
- "请问"
- "question"
- "help"
body_patterns:
- "我刚开始用"
- "新手"
- "文档没写"
# doctracker_id: 4
doc:
title_patterns:
- "文档"
- "README"
- "教程"
- "doc"
- "typo"
- "拼写"
- "错别字"
body_patterns:
- "文档不全"
- "示例无法运行"
# supporttracker_id: 3
support:
title_patterns:
- "支持"
- "求助"
- "support"
- "咨询"
- "如何配置"
```
### 3.2 Priority 规则
```yaml
urgent:
patterns:
- "紧急"
- "urgent"
- "ASAP"
- "线上"
- "production"
- "数据丢失"
- "数据泄露"
- "安全"
- "security"
- "CVE"
- "RCE"
- "越权"
high:
patterns:
- "重要"
- "阻塞"
- "block"
- "无法工作"
- "完全不能用"
- "high"
- "所有用户"
- "全员受影响"
low:
patterns:
- "minor"
- "小问题"
- "nice to have"
- "低优"
- "不急"
- "建议"
- "锦上添花"
# 默认 normal无任何上述信号
```
---
## 4. 置信度计算
```python
confidence = 0.0
signals = 0
# tracker 决策信号
if title_match:
confidence += 0.4
signals += 1
if body_match:
confidence += 0.2
signals += 1
if multiple_match_conflict:
confidence -= 0.15
# priority 决策信号
if urgent_or_high_signal:
confidence += 0.2
signals += 1
# 关联 Issue 强信号
if duplicate_score >= 0.7:
confidence += 0.15
signals += 1
# 描述长度(信息量)
if len(description) < 20:
confidence -= 0.2 # 信息不足
# AI 语义判断的额外加权
if ai_semantic_decision:
confidence += 0.1
# 归一化到 [0, 1]
confidence = max(0, min(1, confidence))
```
**阈值**
- `confidence >= 0.7` → 直接应用
- `0.5 <= confidence < 0.7` → 应用但标记"建议复核"
- `confidence < 0.5`**不应用**,仅放入"待人工"队列
---
## 5. 关联 Issue 算法
### 5.1 文本预处理
```python
def tokenize(text):
# 中文2-gram 字符切片
# 英文:小写化 + 词形还原
# 去停用词("的", "了", "the", "a", "an", ...
tokens = set()
# ... implementation
return tokens
```
### 5.2 Jaccard 相似度
```python
def jaccard(a: set, b: set) -> float:
if not a or not b:
return 0.0
return len(a & b) / len(a | b)
```
### 5.3 关联决策
| 相似度 | 决策 |
|--------|------|
| ≥ 0.7 且一方已关闭 | 推荐 mark as duplicate |
| ≥ 0.7 双方都开 | 评论"可能与 #X 相关" |
| 0.4 - 0.7 | 列入"可能相关",由人工判断 |
| < 0.4 | 不关联 |
---
## 6. 输出 Schema
完整分析报告遵循以下 JSON Schema简化版
```json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["repository", "analyzed_at", "total", "items"],
"properties": {
"repository": {"type": "string", "pattern": "^[^/]+/[^/]+$"},
"analyzed_at": {"type": "string", "format": "date-time"},
"total": {"type": "integer", "minimum": 0},
"by_tracker": {
"type": "object",
"additionalProperties": {"type": "integer"}
},
"by_priority": {
"type": "object",
"additionalProperties": {"type": "integer"}
},
"items": {
"type": "array",
"items": {
"type": "object",
"required": ["number", "title", "decisions", "confidence"],
"properties": {
"number": {"type": "integer"},
"title": {"type": "string"},
"current_tracker": {"type": ["string", "null"]},
"current_labels": {"type": "array", "items": {"type": "string"}},
"decisions": {
"type": "object",
"required": ["tracker", "priority"],
"properties": {
"tracker": {"type": "string", "enum": ["bug", "feature", "support", "doc", "test", "duplicate", "question"]},
"priority": {"type": "string", "enum": ["low", "normal", "high", "urgent"]},
"labels": {"type": "array", "items": {"type": "string"}},
"assignee": {"type": ["string", "null"]},
"related_issues": {"type": "array", "items": {"type": "integer"}},
"mark_duplicate": {"type": ["integer", "null"]}
}
},
"confidence": {"type": "number", "minimum": 0, "maximum": 1},
"reasoning": {"type": "string"},
"matched_rules": {"type": "array", "items": {"type": "string"}},
"needs_review": {"type": "boolean"}
}
}
}
}
}
```
---
## 7. 边界情况处理
| 情况 | 处理 |
|------|------|
| Issue 无正文 | confidence 上限 0.5;强制 needs_review=true |
| 标题过长(> 100 字) | 截取前 50 字做匹配 |
| 标题全英文 | 跳过中文规则,仅用英文规则 |
| 仓库无任何标签 | 跳过 Stage D在报告中提示 |
| @mention 用户不在 assigners 列表 | 不指派,提示"权限不足" |
| 历史 Issue < 5 | 跳过关联推荐 |
| 已有 tracker 的 Issue | 默认不覆盖,除非用户加 `--force` |
---
## 8. 性能建议
| 规模 | 建议 |
|------|------|
| ≤ 20 个 Issue | 单次分析,内存缓存元数据 |
| 20-100 个 | 分批 20/批,每批后用户确认 |
| > 100 个 | 强制分批,每批 20建议夜间运行 |
API 调用次数估算:`N * 1 (view) + 3 (元数据) + N * 0.3 (平均关联)` ≈ `1.3N + 3`
---
## 9. 参考实现
伪代码Python-like
```python
def triage_issue(issue, repo_meta, history):
text = normalize(issue.subject + " " + issue.description)
# Stage B: tracker
tracker, tracker_rules = decide_tracker(text)
# Stage C: priority
priority, priority_rules = decide_priority(text)
# Stage D: labels
labels = match_labels(tracker, priority, repo_meta.tags)
# Stage E: assignee
assignee = parse_mention(issue.description, repo_meta.assigners)
# Stage F: related
related, duplicate = find_related(issue, history)
# Stage G: confidence
confidence = compute_confidence(
tracker_rules, priority_rules, duplicate, len(issue.description)
)
return {
"number": issue.number,
"decisions": {
"tracker": tracker,
"priority": priority,
"labels": labels,
"assignee": assignee,
"related_issues": related,
"mark_duplicate": duplicate,
},
"confidence": confidence,
"matched_rules": tracker_rules + priority_rules,
"needs_review": confidence < 0.7,
}
```
完整可运行实现请参考 [examples/triage-batch-workflow.md](../examples/triage-batch-workflow.md) 中的 AI Agent 提示词。

View File

@ -0,0 +1,277 @@
# gitlink-issue-triage — 应用变更手册
> 本文档说明如何把分析报告中的决策**安全地**应用到 GitLink Issue。
> 所有命令默认 dry-run确认后再去掉 `--dry-run` 实际执行。
## 1. 应用前置检查
### 1.1 备份当前状态
```bash
# 导出当前所有目标 Issue 的原始字段(用于回滚)
gitlink-cli issue +list --state open --format json > /tmp/before-triage.json
```
### 1.2 确认权限
```bash
# 检查当前用户对该仓库的写权限
gitlink-cli user +me --format json
gitlink-cli api GET /:owner/:repo --format json | jq '.data.permissions'
```
`permissions.push !== true`,应用变更会失败,应停止并提示用户。
---
## 2. 单 Issue 应用流程
针对报告中的每个 item
### 2.1 应用 tracker类型
```bash
# 注意GitLink v1 API 通过 tracker_id 字段更新
gitlink-cli issue +update \
--owner <owner> \
--repo <repo> \
--number <N> \
--state in-progress # 顺带把状态从 new 改为 in-progress
```
> ⚠️ **当前 gitlink-cli 的 `+update` 不直接支持改 tracker**
> 如需改 tracker使用 Raw API
>
> ```bash
> # tracker_id: 1=bug, 2=feature, 3=support, 4=doc, 5=test, 6=duplicate, 7=question
> gitlink-cli api PATCH /v1/<owner>/<repo>/issues/<N> \
> --body '{"subject":"< subject>","description":"< description>","tracker_id":1}'
> ```
>
> **必须**先 GET 当前 Issue 拿到 `subject``description`,否则会被清空。
### 2.2 应用 priority优先级
```bash
# priority_id: 1=low, 2=normal, 3=high, 4=urgent
gitlink-cli api PATCH /v1/<owner>/<repo>/issues/<N> \
--body '{"subject":"<>","description":"<>","priority_id":3}'
```
### 2.3 应用 labels标签
```bash
# 方法 A用 +label-add推荐自动处理 name→id
gitlink-cli issue +label-add \
--owner <owner> --repo <repo> \
--number <N> \
--labels "缺陷,紧急"
# 方法 BRaw API需要预先查标签 ID
LABEL_IDS=$(echo "缺陷,紧急" | tr ',' '\n' | while read name; do
gitlink-cli api GET /v1/<owner>/<repo>/issue_tags.json --format json \
| jq -r --arg n "$name" '.data.issue_tags[] | select(.name==$argn) | .id'
done | paste -sd, -)
gitlink-cli api POST /v1/<owner>/<repo>/issues/<N>/labels \
--body "{\"labels\":\"$LABEL_IDS\"}"
```
### 2.4 应用 assignee指派人
> ⚠️ **默认不自动指派个人**,除非用户明确同意。
> 推荐做法:在评论中 @mention 建议由 PM 分配。
```bash
# 若用户明确要求指派:
gitlink-cli issue +update \
--owner <owner> --repo <repo> \
--number <N> \
--body "< description>" # 占位update 至少要改一个字段
# 或通过 Raw API更可控
USER_ID=$(gitlink-cli api GET /users/<login> --format json | jq '.data.id')
gitlink-cli api PATCH /v1/<owner>/<repo>/issues/<N> \
--body "{\"subject\":\"<>\",\"description\":\"<>\",\"assigned_to_id\":$USER_ID}"
```
### 2.5 应用 comment评论 + 关联 Issue
```bash
# 生成评论内容Markdown
COMMENT_BODY=$(cat <<'EOF'
🤖 **自动分类报告**
| 字段 | 决策 | 依据 |
|------|------|------|
| 类型 | bug | 标题含"无反应" |
| 优先级 | high | 正文提"线上" |
| 标签 | 缺陷, 紧急 | 仓库标签匹配 |
**关联 Issue**:可能与 #138"登录页加载失败")相关。
如分类有误请回复 `/triage incorrect`,我会重新分析。
EOF
)
gitlink-cli issue +comment \
--owner <owner> --repo <repo> \
--number <N> \
--body "$COMMENT_BODY"
```
### 2.6 标记 duplicate可选
```bash
# 仅评论建议,不主动关闭
gitlink-cli issue +comment \
--number <N> \
--body "检测到本 Issue 与 #138 高度相似(相似度 0.82),建议维护者判断是否标记为重复。"
```
---
## 3. 批量应用模板
### 3.1 Shell 脚本(推荐)
```bash
#!/usr/bin/env bash
# apply-triage.sh — 从 report.json 应用分类决策
set -euo pipefail
OWNER="${1:?usage: apply-triage.sh <owner>/<repo> <report.json>}"
REPO="${2:?missing repo}"
REPORT="${3:?missing report.json}"
# 读取报告
TOTAL=$(jq '.total' "$REPORT")
echo "Will apply triage decisions to $TOTAL issues in $OWNER/$REPO"
read -rp "Proceed? (yes/no) " CONFIRM
[ "$CONFIRM" = "yes" ] || { echo "aborted"; exit 1; }
# 逐条应用
jq -c '.items[]' "$REPORT" | while read -r item; do
NUM=$(echo "$item" | jq '.number')
TRACKER=$(echo "$item" | jq -r '.decisions.tracker')
PRIORITY=$(echo "$item" | jq -r '.decisions.priority')
CONF=$(echo "$item" | jq '.confidence')
echo "→ Issue #$NUM (tracker=$TRACKER, priority=$PRIORITY, conf=$CONF)"
# 跳过低置信度
if (( $(echo "$CONF < 0.5" | bc -l) )); then
echo " skipped (low confidence)"
continue
fi
# ... 调用上面的应用命令
# 避免限流
sleep 0.5
done
echo "Done. Summary written to /tmp/after-triage.json"
```
### 3.2 AI Agent 执行模板
向 Claude Code 发送:
```
请按以下步骤应用 /tmp/triage-report.json 中的决策:
1. 读取报告,过滤 confidence < 0.5 的项
2. 对每个剩余项:
a. 用 Raw API PATCH 更新 tracker_id 和 priority_id注意保留 subject/description
b. 用 issue +label-add 添加 labels
c. 用 issue +comment 评论分析摘要
3. 每应用 5 个后暂停,问我是否继续
4. 完成后输出统计:成功数、失败数、跳过数
任何步骤失败都不要继续,停下来问我。
```
---
## 4. 回滚策略
### 4.1 自动备份
应用前已执行:
```bash
gitlink-cli issue +list --state all --format json > /tmp/before-triage-$(date +%s).json
```
### 4.2 回滚单 Issue
```bash
# 从备份恢复原始字段
ORIGINAL=$(jq '.data.issues[] | select(.number==142)' /tmp/before-triage.json)
gitlink-cli api PATCH /v1/<owner>/<repo>/issues/142 \
--body "$(echo "$ORIGINAL" | jq '{subject, description, tracker_id, priority_id, status_id}')"
# 移除新加的标签
gitlink-cli issue +label-remove --number 142 --label "缺陷"
gitlink-cli issue +label-remove --number 142 --label "紧急"
```
### 4.3 批量回滚
```bash
# 反向应用 before-triage.json把每个 Issue 恢复到原始状态
# 谨慎:会丢失 triage 之后的人工修改
./apply-triage-rollback.sh <owner>/<repo> /tmp/before-triage.json
```
---
## 5. 错误处理
| 错误 | 原因 | 处理 |
|------|------|------|
| `HTTP 401` | Token 失效 | `gitlink-cli auth login` |
| `HTTP 403` | 无写权限 | 联系仓库 owner |
| `HTTP 404` | Issue 编号错或已删除 | 跳过,记录到 errors |
| `HTTP 422` | subject/description 被清空 | 必须先 GET 再 PATCH |
| `status: -1` | 参数错 | 检查 tracker_id/priority_id 数值 |
应用失败时**不要重试**,记录到错误日志,整体应用结束后人工排查。
---
## 6. 审计日志
每次应用后记录:
```json
{
"applied_at": "2026-06-16T10:30:00Z",
"operator": "ai-agent + human-confirm",
"batch_id": "triage-20260616-1",
"items_applied": [
{
"number": 142,
"changes": {
"tracker_id": {"from": null, "to": 1},
"priority_id": {"from": 2, "to": 3},
"labels_added": ["缺陷", "紧急"]
},
"success": true
}
]
}
```
保存到 `/tmp/triage-audit-<timestamp>.json`,便于追溯。
---
## 7. 最佳实践
- ✅ **小批量试水**:先对 3-5 个 Issue 应用,观察结果再扩大
- ✅ **敏感词过滤**:对 urgent 决策额外人工复核
- ✅ **避开高峰**:大批量应用安排在用户活跃低谷时段
- ✅ **通知 owner**:通过 `issue +comment` 在首个 Issue 中说明"本批为自动分类"
- ❌ **禁止**:跳过 dry-run 直接批量应用
- ❌ **禁止**:对 archived 或 read-only 仓库执行