From 5a590f68508d7e1bcf0abcb85d83d24182f0da95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8B=97gogo?= Date: Tue, 16 Jun 2026 08:54:56 +0800 Subject: [PATCH] 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 --- skills/gitlink-code-review/README.md | 362 ++++++++++ skills/gitlink-code-review/REFERENCE.md | 579 +++++++++++++++ skills/gitlink-code-review/SKILL.md | 284 ++++++++ .../examples/auto-review-pr.md | 420 +++++++++++ .../examples/basic-review-workflow.md | 286 ++++++++ .../examples/comprehensive-review-workflow.md | 407 +++++++++++ .../references/code-review-analyze.md | 403 +++++++++++ .../references/code-review-quality.md | 388 ++++++++++ .../references/code-review-security.md | 520 +++++++++++++ skills/gitlink-code-review/skill_test.md | 682 ++++++++++++++++++ skills/gitlink-issue-triage/README.md | 132 ++++ skills/gitlink-issue-triage/SKILL.md | 268 +++++++ .../examples/triage-batch-workflow.md | 472 ++++++++++++ .../examples/triage-single-issue.md | 269 +++++++ .../gitlink-issue-triage-analyze.md | 434 +++++++++++ .../references/gitlink-issue-triage-apply.md | 277 +++++++ 16 files changed, 6183 insertions(+) create mode 100644 skills/gitlink-code-review/README.md create mode 100644 skills/gitlink-code-review/REFERENCE.md create mode 100644 skills/gitlink-code-review/SKILL.md create mode 100644 skills/gitlink-code-review/examples/auto-review-pr.md create mode 100644 skills/gitlink-code-review/examples/basic-review-workflow.md create mode 100644 skills/gitlink-code-review/examples/comprehensive-review-workflow.md create mode 100644 skills/gitlink-code-review/references/code-review-analyze.md create mode 100644 skills/gitlink-code-review/references/code-review-quality.md create mode 100644 skills/gitlink-code-review/references/code-review-security.md create mode 100644 skills/gitlink-code-review/skill_test.md create mode 100644 skills/gitlink-issue-triage/README.md create mode 100644 skills/gitlink-issue-triage/SKILL.md create mode 100644 skills/gitlink-issue-triage/examples/triage-batch-workflow.md create mode 100644 skills/gitlink-issue-triage/examples/triage-single-issue.md create mode 100644 skills/gitlink-issue-triage/references/gitlink-issue-triage-analyze.md create mode 100644 skills/gitlink-issue-triage/references/gitlink-issue-triage-apply.md diff --git a/skills/gitlink-code-review/README.md b/skills/gitlink-code-review/README.md new file mode 100644 index 0000000..bc33ac9 --- /dev/null +++ b/skills/gitlink-code-review/README.md @@ -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 分析并生成报告 +# 修复发现的问题 +``` + +### 场景 2:Reviewers 辅助审查 + +Reviewers 使用 AI 辅助审查: +```bash +# 快速获取审查报告 +gitlink-cli pr +view --id 123 --format json +gitlink-cli pr +diff --id 123 --format json + +# AI 生成报告,Reviewers 参考 +# 专注于业务逻辑和架构设计 +``` + +### 场景 3:CI/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/) 中的详细示例。 diff --git a/skills/gitlink-code-review/REFERENCE.md b/skills/gitlink-code-review/REFERENCE.md new file mode 100644 index 0000000..37380d7 --- /dev/null +++ b/skills/gitlink-code-review/REFERENCE.md @@ -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 --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 --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 --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": "", + "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* diff --git a/skills/gitlink-code-review/SKILL.md b/skills/gitlink-code-review/SKILL.md new file mode 100644 index 0000000..371e7a4 --- /dev/null +++ b/skills/gitlink-code-review/SKILL.md @@ -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 --format json + +# 2. 获取变更文件列表 +gitlink-cli pr +files --id --format json + +# 3. 获取 diff 内容 +gitlink-cli pr +diff --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 --format json + ``` + +2. **获取代码变更** + ```bash + gitlink-cli pr +files --id --format json + gitlink-cli pr +diff --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 代码审查指南 diff --git a/skills/gitlink-code-review/examples/auto-review-pr.md b/skills/gitlink-code-review/examples/auto-review-pr.md new file mode 100644 index 0000000..e957585 --- /dev/null +++ b/skills/gitlink-code-review/examples/auto-review-pr.md @@ -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 分钟 +- **中 PR(100-500 行)**: 1-3 分钟 +- **大 PR(500-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* diff --git a/skills/gitlink-code-review/examples/basic-review-workflow.md b/skills/gitlink-code-review/examples/basic-review-workflow.md new file mode 100644 index 0000000..a73ebde --- /dev/null +++ b/skills/gitlink-code-review/examples/basic-review-workflow.md @@ -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* diff --git a/skills/gitlink-code-review/examples/comprehensive-review-workflow.md b/skills/gitlink-code-review/examples/comprehensive-review-workflow.md new file mode 100644 index 0000000..d2bf78d --- /dev/null +++ b/skills/gitlink-code-review/examples/comprehensive-review-workflow.md @@ -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 < 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 < 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* diff --git a/skills/gitlink-code-review/references/code-review-analyze.md b/skills/gitlink-code-review/references/code-review-analyze.md new file mode 100644 index 0000000..30c30b1 --- /dev/null +++ b/skills/gitlink-code-review/references/code-review-analyze.md @@ -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 --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 --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 --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* diff --git a/skills/gitlink-code-review/references/code-review-quality.md b/skills/gitlink-code-review/references/code-review-quality.md new file mode 100644 index 0000000..fa962d6 --- /dev/null +++ b/skills/gitlink-code-review/references/code-review-quality.md @@ -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* diff --git a/skills/gitlink-code-review/references/code-review-security.md b/skills/gitlink-code-review/references/code-review-security.md new file mode 100644 index 0000000..8ccf52c --- /dev/null +++ b/skills/gitlink-code-review/references/code-review-security.md @@ -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, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'"); +} +``` + +**修复建议**: +1. 对用户输入进行 HTML 转义 +2. 使用 `textContent` 而非 `innerHTML` +3. 使用 CSP(Content 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 + +``` + +### 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* diff --git a/skills/gitlink-code-review/skill_test.md b/skills/gitlink-code-review/skill_test.md new file mode 100644 index 0000000..c4973c8 --- /dev/null +++ b/skills/gitlink-code-review/skill_test.md @@ -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 --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 中执行**: + +``` +用户: 我需要审查一个 PR,PR 编号是 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 <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 +``` + +--- + +## 📞 获取帮助 + +如果测试过程中遇到问题: + +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* diff --git a/skills/gitlink-issue-triage/README.md b/skills/gitlink-issue-triage/README.md new file mode 100644 index 0000000..64a3df0 --- /dev/null +++ b/skills/gitlink-issue-triage/README.md @@ -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)。 diff --git a/skills/gitlink-issue-triage/SKILL.md b/skills/gitlink-issue-triage/SKILL.md new file mode 100644 index 0000000..5f855ba --- /dev/null +++ b/skills/gitlink-issue-triage/SKILL.md @@ -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-triage(Issue 自动分类) + +**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 --format json` | 获取 Issue 详情(标题/正文/标签) | +| `issue +label-list --number --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 --state ` | 改状态(如 in-progress) | +| `issue +label-add --number --labels ""` | 加标签 | +| `issue +comment --number --body ""` | 评论(关联 Issue 链接、分析摘要) | +| `issue +batch-label --label --numbers ` | 批量改 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 --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` 反向恢复。 diff --git a/skills/gitlink-issue-triage/examples/triage-batch-workflow.md b/skills/gitlink-issue-triage/examples/triage-batch-workflow.md new file mode 100644 index 0000000..8ca19e3 --- /dev/null +++ b/skills/gitlink-issue-triage/examples/triage-batch-workflow.md @@ -0,0 +1,472 @@ +# 示例:批量分类工作流(端到端) + +> 本示例演示 AI Agent(Claude 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 + +# 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.json,schema 见 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.7):12 个,可直接应用 +- 待人工复核(<0.7):3 个,建议跳过或人工判断 + +是否应用高置信度项?[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 <.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-.json +``` + +--- + +## 关键检查点 + +- ✅ Step 1 完成后,用户确认范围 +- ✅ Step 4 完成后,用户确认应用 yes +- ✅ Step 5 中每 5 个 Issue 暂停一次(可选) +- ✅ Step 6 完成后,验证至少 3 个 Issue 字段正确 + +--- + +## 性能数据(实测) + +| 阶段 | API 调用次数 | 耗时 | +|------|-------------|------| +| Step 1-2 | 4 | 8s | +| Step 3 分析 | 0(纯本地) | 90s(AI 推理) | +| 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 分钟,且可审计、可回滚。 diff --git a/skills/gitlink-issue-triage/examples/triage-single-issue.md b/skills/gitlink-issue-triage/examples/triage-single-issue.md new file mode 100644 index 0000000..3b1b968 --- /dev/null +++ b/skills/gitlink-issue-triage/examples/triage-single-issue.md @@ -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 120,macOS 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 → 限流 diff --git a/skills/gitlink-issue-triage/references/gitlink-issue-triage-analyze.md b/skills/gitlink-issue-triage/references/gitlink-issue-triage-analyze.md new file mode 100644 index 0000000..05e9e98 --- /dev/null +++ b/skills/gitlink-issue-triage/references/gitlink-issue-triage-analyze.md @@ -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 +# bug(tracker_id: 1) +bug: + title_patterns: + - "bug" + - "错误" + - "失败" + - "崩溃" + - "异常" + - "报错" + - "不能" + - "无法" + - "crash" + - "error" + - "exception" + - "broken" + - "不工作" + - "无反应" + body_patterns: + - "复现步骤" + - "重现" + - "stack trace" + - "回归" + +# duplicate(tracker_id: 6,优先级仅次于 bug) +duplicate: + title_patterns: + - "重复" + - "duplicate" + - "same as" + - "已经提过" + body_patterns: + - "和 #\\d+ 一样" + - "同 #\\d+" + +# feature(tracker_id: 2) +feature: + title_patterns: + - "feature" + - "希望" + - "建议" + - "新增" + - "支持.*吗" + - "能否添加" + - "enhancement" + - "proposal" + - "想要" + - "如果可以" + body_patterns: + - "use case" + - "use-case" + - "应用场景" + +# question(tracker_id: 7) +question: + title_patterns: + - "怎么" + - "如何" + - "哪里" + - "?" + - "?" + - "请问" + - "question" + - "help" + body_patterns: + - "我刚开始用" + - "新手" + - "文档没写" + +# doc(tracker_id: 4) +doc: + title_patterns: + - "文档" + - "README" + - "教程" + - "doc" + - "typo" + - "拼写" + - "错别字" + body_patterns: + - "文档不全" + - "示例无法运行" + +# support(tracker_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 提示词。 diff --git a/skills/gitlink-issue-triage/references/gitlink-issue-triage-apply.md b/skills/gitlink-issue-triage/references/gitlink-issue-triage-apply.md new file mode 100644 index 0000000..1ceb0a4 --- /dev/null +++ b/skills/gitlink-issue-triage/references/gitlink-issue-triage-apply.md @@ -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 \ + --repo \ + --number \ + --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///issues/ \ +> --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///issues/ \ + --body '{"subject":"<原>","description":"<原>","priority_id":3}' +``` + +### 2.3 应用 labels(标签) + +```bash +# 方法 A:用 +label-add(推荐,自动处理 name→id) +gitlink-cli issue +label-add \ + --owner --repo \ + --number \ + --labels "缺陷,紧急" + +# 方法 B:Raw API(需要预先查标签 ID) +LABEL_IDS=$(echo "缺陷,紧急" | tr ',' '\n' | while read name; do + gitlink-cli api GET /v1///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///issues//labels \ + --body "{\"labels\":\"$LABEL_IDS\"}" +``` + +### 2.4 应用 assignee(指派人) + +> ⚠️ **默认不自动指派个人**,除非用户明确同意。 +> 推荐做法:在评论中 @mention 建议由 PM 分配。 + +```bash +# 若用户明确要求指派: +gitlink-cli issue +update \ + --owner --repo \ + --number \ + --body "<原 description>" # 占位,update 至少要改一个字段 +# 或通过 Raw API(更可控) +USER_ID=$(gitlink-cli api GET /users/ --format json | jq '.data.id') +gitlink-cli api PATCH /v1///issues/ \ + --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 --repo \ + --number \ + --body "$COMMENT_BODY" +``` + +### 2.6 标记 duplicate(可选) + +```bash +# 仅评论建议,不主动关闭 +gitlink-cli issue +comment \ + --number \ + --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 / }" +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///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 / /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-.json`,便于追溯。 + +--- + +## 7. 最佳实践 + +- ✅ **小批量试水**:先对 3-5 个 Issue 应用,观察结果再扩大 +- ✅ **敏感词过滤**:对 urgent 决策额外人工复核 +- ✅ **避开高峰**:大批量应用安排在用户活跃低谷时段 +- ✅ **通知 owner**:通过 `issue +comment` 在首个 Issue 中说明"本批为自动分类" +- ❌ **禁止**:跳过 dry-run 直接批量应用 +- ❌ **禁止**:对 archived 或 read-only 仓库执行