关于 gh-notifications
gh-notifications 是面向 GitHub CLI 用户的通知整理技能,可筛选并排序未读通知,并核实近期活动,避免把旧订阅原因误判为新请求。
主要功能
- 01通过 gh api 获取未读通知
- 02过滤低信号通知类型
- 03按优先级和更新时间排序
- 04核实高优先级项目的近期事件
- 05附 GitHub 链接展示排序结果
适用场景
- 01检查未读 GitHub 动态
- 02找出需要直接处理的请求
- 03区分旧提及与新活动
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dzhuneyt/ skills --skill gh-notifications安装后在 Claude Code 中输入/gh-notifications确认已加载。
详细介绍
GitHub 通知分类
概述
通过 gh api 获取未读的 GitHub 通知,过滤无关信息,按重要性排序,并展示排名靠前的 N 条(默认 5 条),附带可点击的链接。需要已完成身份验证的 gh CLI。
工作流
1. 获取所有未读通知
gh api notifications --paginate --jq '.[] | {
id: .id,
type: .subject.type,
title: .subject.title,
repo: .repository.full_name,
updated: .updated_at,
reason: .reason,
url: .subject.url,
latest_comment_url: .subject.latest_comment_url
}'
2. 过滤无关信息
排序前移除信号较弱的通知类型:
- 始终过滤:
CheckSuite(CI 通过或失败)——仅凭通知本身,这类通知几乎从不需要采取行动 - 降低优先级: 来自第三方仓库的
Release通知,除非用户正在使用该库
3. 为剩余通知排序
按以下优先级排序:
| 优先级 | 标准 |
|---|---|
| P0 — 需要直接采取行动 | reason 为 review_requested、assign 或 mention |
| P1 — Bug 修复和安全问题 | 标题包含 fix:、security、vulnerability、[BUG] 或 breaking |
| P2 — 活跃工作仓库 | 用户拥有或积极参与贡献的仓库中的 PR 和 issue |
| P3 — 功能开发 | 用户参与贡献的仓库中标题含 feat: 的 PR |
| P4 — 其他所有内容 | 讨论、外部仓库的 issue、chore/refactor PR、team_mention |
在每个优先级内,按最近更新时间从新到旧排序。
重要:reason 表示订阅原因,而不是触发原因。 GitHub 的 reason 字段说明用户为何订阅该讨论串——它是持久的,反映的是最初的原因。它并不描述这次未读通知是由什么触发的。一旦用户在讨论串中被 @提及,reason 就会永远保持为 mention;之后即使是无关评论、标签变更,或机器人关闭 issue,也会让该讨论串再次显示为未读,同时仍带有 reason: mention。因此,reason: mention 可能表示“你 3 年前被提及过,而刚刚有人发表了评论”,而不是“你刚刚被提及”。
因此,如果某个讨论串的最新活动与用户无关,那么持久的 mention/review_requested 往往是过时的无关信息,而不是新的请求。在将其排为 P0 之前,务必先检查最近一次事件是否确实涉及用户(见第 4 步)。
reason 字段的含义(摘自 GitHub REST API 文档)。 以下值彼此不同——不要混为一谈:
mention— 用户曾在讨论串中的某处被直接 @提及,包括评论中(不只是正文)。该状态会持续存在——见上文警告。team_mention— 用户所属的团队被 @提及,而不是用户本人。信号较弱 → 默认排为 P4。review_requested— 用户或其所在团队之一被请求审查。排为 P0——但该状态也会持续存在;请确认请求仍然开放且指派给他们。assign— issue/PR 已指派给用户。author— 用户创建了该讨论串。comment— 用户评论过的讨论串中有活动。subscribed— 正在关注该仓库。manual— 用户主动订阅。state_change— 用户关闭或合并了该讨论串。ci_activity— 用户触发的工作流已完成。
4. 识别触发事件,而不只是订阅原因(P0 候选项)
reason 是粘性的(参见步骤 3 中的警告),因此看起来像 P0 的 mention/review_requested 可能已经过时。在将其列为 P0 之前,请确定最近发生的实际事件是什么,以及是否涉及用户。比较用户参与的日期与通知的 updated_at。仅对 P0 候选项(少量)执行此步骤,而不是检查每条通知——每条会额外消耗 1–2 次 API 调用。
列表响应中已经包含 subject.latest_comment_url——这是指向最新评论的链接。直接获取该评论,而不是重新列出所有评论。注意:它只指向评论。如果触发事件不是评论(例如 issue 关闭、添加标签或重新打开),latest_comment_url 就已过时或为空——此时改查 issue 状态或 Timeline API。
ME=$(gh api user --jq '.login')
# Cheapest: fetch the exact comment that bumped the thread (from subject.latest_comment_url)
gh api {latest_comment_url} --jq '{user: .user.login, created: .created_at, url: .html_url, body: .body}'
# Catch non-comment triggers (close/reopen/label) that latest_comment_url misses
gh api repos/{owner}/{repo}/issues/{n} --jq '{state, closed_at, updated_at}'
# Where/when was the user actually @mentioned? (may be old). NOTE: pipe to standalone jq — gh api has no --arg
gh api repos/{owner}/{repo}/issues/{n}/comments \
| jq --arg me "$ME" '.[] | select(.body | test("@" + $me + "(?![A-Za-z0-9-])"; "i")) | {user: .user.login, created: .created_at, url: .html_url, body: .body}'
# Full event fidelity (who did what, when) — every close/label/mention/review as discrete events
gh api repos/{owner}/{repo}/issues/{n}/timeline --jq '.[] | {event: .event, actor: .actor.login, created: .created_at}'
判断:
- 最近的事件涉及用户(新鲜的 @提及、刚收到审核请求、有人回复了用户的评论)→ 保持 P0,深度链接到该事件(
.html_url)并引用相关内容。 - 最近的事件无关(其他人的评论、机器人关闭 issue 或添加标签、其他用户执行的
state_change)→ 降级。如实标注,例如“2023 年被提及;因 @other 的新评论再次出现”或“issue 已由机器人关闭——可能只是归档处理”。不要把它说成新的请求。
5. 创建可点击的链接
将 API URL 转换为浏览器 URL:
https://api.github.com/repos/{owner}/{repo}/pulls/{n}→https://github.com/{owner}/{repo}/pull/{n}https://api.github.com/repos/{owner}/{repo}/issues/{n}→https://github.com/{owner}/{repo}/issues/{n}- 对于 Discussion 类型,构造链接:
https://github.com/{owner}/{repo}/discussions
6. 呈现结果
输出一个编号列表,包含:
- 优先级标签(P0-P4)
- 通知类型(Issue、PR、Discussion)
- 标题
- 可点击的 GitHub 链接(对于
mention项,深度链接到提及用户的评论) - 简要说明其优先级较高的原因(一个短语)。对于提及,引用 @提及内容并注明是谁写的——不能只写“有人提到了你”。
示例输出:
1. [P0] PR: feat: Add stress testing helper endpoints
https://github.com/protokol/dpp-api/pull/343
Review requested from you
2. [P1] Issue: [BUG] Statusline context_window JSON...
https://github.com/anthropics/claude-code/issues/13783
Bug report, updated today
3. [P4] Issue: AWS::CertificateManager::Certificate deletion fails...
https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/837
reason=mention but stale: you were @mentioned in 2023; resurfaced by @marat-affinidi's new comment — not a fresh ask
7. 提供后续操作
列出前 N 条后,询问:
- “要我将其余通知标记为已读吗?”
- “要我打开其中的任何一项吗?”
自定义
用户可以使用以下参数调用此 skill:
/gh-notifications— 默认显示前 5 条/gh-notifications 10— 显示前 10 条/gh-notifications --mark-read— 呈现结果后,也将非前列通知标记为已读
常见错误
- 不要逐条获取通知详情(N+1 次 API 调用)——使用
--jq在一次分页调用中提取所需内容 - 不要显示原始 API URL——始终将其转换为可点击的
github.com链接 - 不要将 CheckSuite 通知纳入排名结果——它们纯属噪声
- 不要把
reason当作触发事件。它是粘性的订阅原因——reason: mention可能表示“多年前被提及,现在有人刚刚评论”。将其列为 P0 之前,务必检查最近的事件(步骤 4) - 不要根据
reason字段断言“有人提到了你”(现在时)——提及通常很早就发生了,而且埋在评论中。请核实提及发生的时间和位置,以及是谁触发了当前通知 - 不要把
team_mention当作个人mention——它表示有人标记了你所在的团队,而不是你本人。这是两个不同的reason值