OSS Triage
帮用户从目标仓库里挑出「能接、接得动」的 issue,读完相关代码,输出「选哪个 issue + 大致怎么改」的方案。本技能只读不写:不 fork、不改代码、不留言。
入口:目标仓库有两种来源——
- 用户指定:「我想给 facebook/react 贡献」「帮我看下 cli/cli 这个仓库」
- oss-finder 推荐:上一环节产出的候选清单里选一个
本技能工作目录约定:<root>/<owner>/<repo>(浅克隆,只读分析用)。不污染当前工作区。 <root> 默认 C:/code_proj/github-proj/oss-proj;你口述了别的目录时,用你说的路径替换 <root>。
沟通准则:让人看得懂、跟得上(每个技能都必须遵守)
本技能面向会提需求、但不一定熟悉 GitHub 细节的用户。严格按下面三条做,避免「看不懂 issue」「不知道在干啥」「还得反问我」:
先翻译,再动手。每次拿到 issue / PR 原文,先用 2-3 句大白话告诉用户:
- 这是什么(bug 报告 / 功能请求 / 纯讨论?)
- 报告人到底想要什么
- 做完了长什么样(验收标准)
不要直接把原始 issue body 丢给用户。若用户明显不熟悉 issue / PR / fork 等概念,顺带用一句话类比解释(例如:「issue 就像在公共笔记本上贴一张便利贴提需求;PR 是你写好代码请求合并」)。
过程实时播报。每个非闲鱼动作(拉 issue、克隆、跑测试、读代码)之前,用一句大白话说明「接下来做什么、为什么」;动作之后用一句说明「刚发生了什么、有什么变化(如:已克隆 / 已定位到某文件)」。让用户始终跟得上进度,不用反复问。
主动给状态小结 + 下一步。每完成一步,给一段极简总结:「当前状态」+「下一步是什么 / 在等什么(你 / maintainer / CI)」。需要用户拍板时,明确列出选项并给出你的推荐,不要留白等用户来问。本技能只读不写,任何 fork / 留言 / 建分支都交给 oss-contribute,但切换前要把「接下来要走哪一步」讲清楚。
操作边界
本技能全部是只读操作,可以自动执行:
gh issue list / gh issue view / gh api repos/<owner>/<repo>/issues
gh search issues / gh search prs
gh repo view
git clone --depth 1(浅克隆到 <root>/<owner>/<repo>)
- 工作区内的
Grep / Read / Glob 读代码
本技能不创建 fork、不写 issue 评论、不建分支、不 push。一切结果只输出给用户看。
进入技能后先做
- 确认 gh CLI 已登录:
gh auth status
- 确定目标仓库
<owner>/<repo>:
- 用户已指定 → 直接用
- 未指定 → 提示用户先执行 oss-finder,或直接给一个仓库名
- 看仓库基本信息与贡献指南:
gh repo view <owner>/<repo>
gh api repos/<owner>/<repo>/contents/CONTRIBUTING.md --jq .name 2>/dev/null
场景 1:给一个仓库挑可接的 issue
触发语义:
- "给 挑个 issue"
- "这个项目有什么能做的"
- "看看 cli/cli 有没有适合我的任务"
流程:
拉候选 issue。分两路拉,合并去重:
gh issue list --repo <owner>/<repo> --state open --label "good first issue" \
--limit 50 --json number,title,labels,assignees,createdAt,commentsCount,url
gh issue list --repo <owner>/<repo> --state open --label "help wanted" \
--limit 50 --json number,title,labels,assignees,createdAt,url
评论详情在下一步用 gh issue view --comments 看,列表阶段只拿基础字段。
过滤掉不可接的:
assignees 非空 → 已有人接,跳过
- issue 是纯讨论 / 提问(标题含「how to」「question」,或 body 是问题不是任务)→ 跳过
- 有未合 PR 在改同一件事(见第 3 步验证)→ 跳过
- 最近评论里 maintainer 明确说「已修复 / 过期 / 不需要了」→ 跳过
逐个深看候选 issue(对 2-4 个最有希望的):
gh issue view <number> --repo <owner>/<repo> --comments \
--json number,title,body,state,labels,assignees,createdAt,closedAt,comments
先给用户一句大白话翻译这个 issue 在说什么(是什么 / 报告人想要什么 / 做完什么样),再展开下面的检查要点。
检查要点:
- 是否有人在做:comments 里有没有人自告奋勇「I'll take this」;用
gh search prs "repo:<owner>/<repo> is:open <标题关键词>" 看有没有关联 PR
- 是否仍然有效:body 描述的 bug / 需求是否还成立
- 描述是否清晰:有没有复现步骤 / 期望行为 / 验收标准;描述模糊的要降低优先级
- maintainer 态度:有没有 maintainer 回复过、有没有贴过相关代码位置
浅克隆并读代码,验证「接这个 issue 要动哪些文件、难度如何」:
mkdir -p <root>/<owner>
git clone --depth 1 https://github.com/<owner>/<repo>.git <root>/<owner>/<repo>
已存在则更新:
git -C <root>/<owner>/<repo> fetch --depth 1 origin
git -C <root>/<owner>/<repo> reset --hard origin/HEAD
然后在 <root>/<owner>/<repo> 里用 Grep / Read / Glob 定位 issue 涉及的代码:
- 按 issue body 里的关键词(报错信息、函数名、模块名)搜索
- 读相关文件确认改动面
- 对 bug 类 issue:尽量在代码里走一遍问题路径,判断「问题是否真存在」
输出选题建议,对每个深入看过的 issue 给出:
## 选题建议:<owner>/<repo>
### 候选 1:#<number> <issue 标题>
- 现状:3 天前创建,未分配,无关联 PR,maintainer 回复过
- 问题本质:<一句话>
- 改动面:涉及 `src/xxx.py`、`tests/test_xxx.py`,约 2 个文件
- 改动思路:<大致方案,含关键函数/位置>
- 风险:需要处理 XXX 边界情况
- 建议:✅ 适合接(理由) / ⚠️ 有风险(理由) / ❌ 不建议(理由)
最后明确给出推荐接哪个 issue,以及下一步走 oss-contribute。
场景 2:用户指定某个具体 issue
触发语义:
- "看看 #123 这个 issue 能不能接"
- "帮我评估一下这个任务"
流程:
- 拉 issue 全文和评论:
gh issue view <number> --repo <owner>/<repo> --comments \
--json number,title,body,state,labels,assignees,createdAt,comments
拉到后先翻译(见上方「沟通准则」第 1 条),再检查。
- 按场景 1 第 3 步的要点逐项检查(是否被认领 / 是否有 PR / 是否仍有效)。
- 浅克隆读代码,验证问题是否真实存在、改动面多大。
- 输出结论:能接 / 不能接,及理由和改动思路。
场景 3:仓库里根本没有适合的 issue
触发语义:
- 场景 1 过滤后一个都不剩
- 仓库的 issue 全是讨论、全是已认领
流程:
- 明确告知用户该仓库当前没有可接的任务,不要硬挑。
- 给出三个选项:
- 换仓库:回 oss-finder 换下一个候选
- 放宽标签:去掉 good first issue 限制,看全部 open issue(
gh issue list --repo <owner>/<repo> --state open --limit 100),但提醒用户这些可能门槛更高
- 转向文档 / 测试贡献:检查有没有「改进文档」类 issue,或 README 有没有过时的部分——这类贡献对新手最友好
- 等用户决定后再继续。
异常处理
gh 未登录
引导 gh auth login(需要 repo 权限),完成后重试。
浅克隆失败(网络 / 仓库过大)
issue 描述含糊,无法判断改动面
不要猜。把「信息不足」作为结论之一写进选题建议,标记为 ⚠️,并列出需要 maintainer 澄清的问题。建议用户:要么换 issue,要么接受「先留言问清楚再动手」的路径(留言操作在 oss-contribute 中做)。
候选 issue 都指向同一块代码
说明该模块是热点,多个人可能在抢。优先选指向冷门模块的 issue,避免提交时撞车。
完成报告
- 目标仓库与基本信息
- 看过的 issue 数、过滤原因
- 每个深入 issue 的「现状 / 问题本质 / 改动面 / 思路 / 风险」
- 明确的选题结论 + 下一步(oss-contribute)
- 结尾必须给一句「下一步是什么 / 在等什么(你 / maintainer / CI)」,不要留白让用户来问。
1---2name: oss-triage3description: GitHub 开源贡献第二步:选 issue + 读代码。给定目标仓库(用户指定或 oss-finder 选出的候选),用 gh CLI 拉取候选 issue(good first issue / help wanted),筛选出「未分配、无关联 PR、仍有效」的可接 issue,浅克隆到 <root> 读代码,验证 issue 现状并给出「选题 + 改动方案」。触发词:「给 <repo> 挑个 issue」「这个项目能做什么」「看看这个 issue 能不能接」。4---56# OSS Triage78帮用户从目标仓库里挑出「能接、接得动」的 issue,读完相关代码,输出「选哪个 issue + 大致怎么改」的方案。本技能只读不写:不 fork、不改代码、不留言。910**入口**:目标仓库有两种来源——11- 用户指定:「我想给 facebook/react 贡献」「帮我看下 cli/cli 这个仓库」12- oss-finder 推荐:上一环节产出的候选清单里选一个1314本技能工作目录约定:`<root>/<owner>/<repo>`(浅克隆,只读分析用)。**不污染当前工作区。** `<root>` 默认 `C:/code_proj/github-proj/oss-proj`;你口述了别的目录时,用你说的路径替换 `<root>`。1516---1718## 沟通准则:让人看得懂、跟得上(每个技能都必须遵守)1920本技能面向**会提需求、但不一定熟悉 GitHub 细节**的用户。严格按下面三条做,避免「看不懂 issue」「不知道在干啥」「还得反问我」:21221. **先翻译,再动手**。每次拿到 issue / PR 原文,先用 2-3 句大白话告诉用户:23 - 这是什么(bug 报告 / 功能请求 / 纯讨论?)24 - 报告人到底想要什么25 - 做完了长什么样(验收标准)26 27 不要直接把原始 issue body 丢给用户。若用户明显不熟悉 issue / PR / fork 等概念,顺带用一句话类比解释(例如:「issue 就像在公共笔记本上贴一张便利贴提需求;PR 是你写好代码请求合并」)。28292. **过程实时播报**。每个非闲鱼动作(拉 issue、克隆、跑测试、读代码)之前,用一句大白话说明「接下来做什么、为什么」;动作之后用一句说明「刚发生了什么、有什么变化(如:已克隆 / 已定位到某文件)」。让用户始终跟得上进度,不用反复问。30313. **主动给状态小结 + 下一步**。每完成一步,给一段极简总结:「当前状态」+「下一步是什么 / 在等什么(你 / maintainer / CI)」。需要用户拍板时,明确列出选项并给出**你的推荐**,不要留白等用户来问。本技能只读不写,任何 fork / 留言 / 建分支都交给 oss-contribute,但切换前要把「接下来要走哪一步」讲清楚。3233## 操作边界3435本技能全部是**只读**操作,可以自动执行:36- `gh issue list` / `gh issue view` / `gh api repos/<owner>/<repo>/issues`37- `gh search issues` / `gh search prs`38- `gh repo view`39- `git clone --depth 1`(浅克隆到 `<root>/<owner>/<repo>`)40- 工作区内的 `Grep` / `Read` / `Glob` 读代码4142本技能**不**创建 fork、不写 issue 评论、不建分支、不 push。一切结果只输出给用户看。4344---4546## 进入技能后先做47481. 确认 gh CLI 已登录:49 ```bash50 gh auth status51 ```522. 确定目标仓库 `<owner>/<repo>`:53 - 用户已指定 → 直接用54 - 未指定 → 提示用户先执行 oss-finder,或直接给一个仓库名553. 看仓库基本信息与贡献指南:56 ```bash57 gh repo view <owner>/<repo>58 gh api repos/<owner>/<repo>/contents/CONTRIBUTING.md --jq .name 2>/dev/null59 ```6061---6263## 场景 1:给一个仓库挑可接的 issue6465触发语义:66- "给 <repo> 挑个 issue"67- "这个项目有什么能做的"68- "看看 cli/cli 有没有适合我的任务"6970流程:71721. **拉候选 issue**。分两路拉,合并去重:73 ```bash74 gh issue list --repo <owner>/<repo> --state open --label "good first issue" \75 --limit 50 --json number,title,labels,assignees,createdAt,commentsCount,url76 gh issue list --repo <owner>/<repo> --state open --label "help wanted" \77 --limit 50 --json number,title,labels,assignees,createdAt,url78 ```79 评论详情在下一步用 `gh issue view --comments` 看,列表阶段只拿基础字段。80812. **过滤掉不可接的**:82 - `assignees` 非空 → 已有人接,跳过83 - issue 是纯讨论 / 提问(标题含「how to」「question」,或 body 是问题不是任务)→ 跳过84 - 有未合 PR 在改同一件事(见第 3 步验证)→ 跳过85 - 最近评论里 maintainer 明确说「已修复 / 过期 / 不需要了」→ 跳过86873. **逐个深看候选 issue**(对 2-4 个最有希望的):88 ```bash89 gh issue view <number> --repo <owner>/<repo> --comments \90 --json number,title,body,state,labels,assignees,createdAt,closedAt,comments91 ```92 **先给用户一句大白话翻译这个 issue 在说什么**(是什么 / 报告人想要什么 / 做完什么样),再展开下面的检查要点。93 检查要点:94 - **是否有人在做**:comments 里有没有人自告奋勇「I'll take this」;用 `gh search prs "repo:<owner>/<repo> is:open <标题关键词>"` 看有没有关联 PR95 - **是否仍然有效**:body 描述的 bug / 需求是否还成立96 - **描述是否清晰**:有没有复现步骤 / 期望行为 / 验收标准;描述模糊的要降低优先级97 - **maintainer 态度**:有没有 maintainer 回复过、有没有贴过相关代码位置98994. **浅克隆并读代码**,验证「接这个 issue 要动哪些文件、难度如何」:100 ```bash101 mkdir -p <root>/<owner>102 git clone --depth 1 https://github.com/<owner>/<repo>.git <root>/<owner>/<repo>103 ```104 已存在则更新:105 ```bash106 git -C <root>/<owner>/<repo> fetch --depth 1 origin107 git -C <root>/<owner>/<repo> reset --hard origin/HEAD108 ```109 然后在 `<root>/<owner>/<repo>` 里用 Grep / Read / Glob 定位 issue 涉及的代码:110 - 按 issue body 里的关键词(报错信息、函数名、模块名)搜索111 - 读相关文件确认改动面112 - 对 bug 类 issue:尽量在代码里走一遍问题路径,判断「问题是否真存在」1131145. **输出选题建议**,对每个深入看过的 issue 给出:115116```markdown117## 选题建议:<owner>/<repo>118119### 候选 1:#<number> <issue 标题>120- 现状:3 天前创建,未分配,无关联 PR,maintainer 回复过121- 问题本质:<一句话>122- 改动面:涉及 `src/xxx.py`、`tests/test_xxx.py`,约 2 个文件123- 改动思路:<大致方案,含关键函数/位置>124- 风险:需要处理 XXX 边界情况125- 建议:✅ 适合接(理由) / ⚠️ 有风险(理由) / ❌ 不建议(理由)126```127128最后明确给出推荐接哪个 issue,以及下一步走 oss-contribute。129130---131132## 场景 2:用户指定某个具体 issue133134触发语义:135- "看看 #123 这个 issue 能不能接"136- "帮我评估一下这个任务"137138流程:1391401. 拉 issue 全文和评论:141 ```bash142 gh issue view <number> --repo <owner>/<repo> --comments \143 --json number,title,body,state,labels,assignees,createdAt,comments144 ```145 **拉到后先翻译**(见上方「沟通准则」第 1 条),再检查。1462. 按场景 1 第 3 步的要点逐项检查(是否被认领 / 是否有 PR / 是否仍有效)。1473. 浅克隆读代码,验证问题是否真实存在、改动面多大。1484. 输出结论:能接 / 不能接,及理由和改动思路。149150---151152## 场景 3:仓库里根本没有适合的 issue153154触发语义:155- 场景 1 过滤后一个都不剩156- 仓库的 issue 全是讨论、全是已认领157158流程:1591601. 明确告知用户该仓库当前没有可接的任务,不要硬挑。1612. 给出三个选项:162 - **换仓库**:回 oss-finder 换下一个候选163 - **放宽标签**:去掉 good first issue 限制,看全部 open issue(`gh issue list --repo <owner>/<repo> --state open --limit 100`),但提醒用户这些可能门槛更高164 - **转向文档 / 测试贡献**:检查有没有「改进文档」类 issue,或 README 有没有过时的部分——这类贡献对新手最友好1653. 等用户决定后再继续。166167---168169## 异常处理170171### gh 未登录172173引导 `gh auth login`(需要 `repo` 权限),完成后重试。174175### 浅克隆失败(网络 / 仓库过大)176177- 先重试一次178- 仍失败:改用 `gh api` 读文件树和单个文件,不下全量代码:179 ```bash180 gh api repos/<owner>/<repo>/git/trees/main?recursive=1 --jq '.tree[].path' | grep -i <关键词>181 gh api repos/<owner>/<repo>/contents/<path> --jq .content | base64 -d182 ```183 并提示用户网络问题,可能需要代理。184185### issue 描述含糊,无法判断改动面186187不要猜。把「信息不足」作为结论之一写进选题建议,标记为 ⚠️,并列出需要 maintainer 澄清的问题。建议用户:要么换 issue,要么接受「先留言问清楚再动手」的路径(留言操作在 oss-contribute 中做)。188189### 候选 issue 都指向同一块代码190191说明该模块是热点,多个人可能在抢。优先选指向冷门模块的 issue,避免提交时撞车。192193---194195## 完成报告196197- 目标仓库与基本信息198- 看过的 issue 数、过滤原因199- 每个深入 issue 的「现状 / 问题本质 / 改动面 / 思路 / 风险」200- 明确的选题结论 + 下一步(oss-contribute)201- 结尾必须给一句「下一步是什么 / 在等什么(你 / maintainer / CI)」,不要留白让用户来问。