mcpField
G
gh-notifications

gh-notifications

github.com/dzhuneyt生产力056 次安装2 周前更新
代码仓库

关于 gh-notifications

gh-notifications 是面向 GitHub CLI 用户的通知整理技能,可筛选并排序未读通知,并核实近期活动,避免把旧订阅原因误判为新请求。

主要功能

  1. 01通过 gh api 获取未读通知
  2. 02过滤低信号通知类型
  3. 03按优先级和更新时间排序
  4. 04核实高优先级项目的近期事件
  5. 05附 GitHub 链接展示排序结果

适用场景

  1. 01检查未读 GitHub 动态
  2. 02找出需要直接处理的请求
  3. 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 值

评论

支持 Markdown