Community写作与编辑github.com

trailofbits/github-triage

通过 gh CLI 分类整理仓库中的未解决的 GitHub Issue 和拉取请求。可选地审查并合并没有审查过的 PR(逐步合并通过的自动化/机器人 PR 和维护者批准的 PR,并生成审查子代理处理从未审查过的 PR),然后关闭已解决的 Issue(附上注释,引用解决该 Issue 的 PR 或提交),将 Issue 与其待修复的 PR 交叉链接,并为所有未完成的 Issue 分配本地优先级的变更规模评估。在需要分类、整理或审查仓库的未解决 Issue 和 PR 时使用。

github-triage 是什么?

GitHub Triage 是一个 AI 辅助技能,用于自动化处理 GitHub 仓库中未解决的问题(Issues)和拉取请求(PRs)的分类流程。它通过 `gh` CLI 接口执行,能够逐步合并机器人自动 PR(如 Dependabot、Renovate)和维护者批准的 PR,为从未审查过的 PR 启动审查子代理,然后关闭已解决但未标记为关闭的 Issue,并确保 Issue 与其修复 PR 之间建立互相引用关系。该技能将优先级和变更规模评估限制在本地,绝不将这些评估写入 GitHub,从而避免了标签噪音。其主要工作流程包括:选择目标仓库、收集所有未解决的 Issues 和 PRs、可选地处理 PRs(合并或审查)、分类 Issue(已解决、有挂起 PR 或未解决)。它严格遵循“写操作需审批”原则——在执行任何合并、关闭或评论操作之前,必须获得用户明确许可。该技能支持标准的 GitHub 仓库以及 GitHub Enterprise 实例(需手动配置),并且要求 `gh` CLI 已通过身份验证。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/trailofbits/skills/tree/main/plugins/github-triage/skills/github-triage

Installed? Explore more 写作与编辑 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

GitHub 分类整理

分类整理仓库的未解决 GitHub Issue 和拉取请求。可选地先处理准备好的 PR(合并通过的机器人 PR 和维护者批准的 PR,审查从未审查过的 PR),然后关闭已解决的 Issue(附上注释,引用解决该 Issue 的 PR 或提交),确保 Issue 及其待修复的 PR 互相引用,并为所有未完成的 Issue 分配一个仅限本地的优先级和变更规模评估。

何时使用

  • 当用户运行 /github-triage 来整理或审查仓库的未解决 Issue 和拉取请求时。
  • 当 Issue 积压任务发生偏离时:已解决的工作仍处于开放状态,修复内容已落地但未关闭其 Issue,或者有正在进行的 PR 从未链接到其 Issue。
  • 当准备好的 PR 已经堆积起来(通过的依赖项更新、已批准且检查通过的 PR)或 PR 一直未被审查时。

何时不使用

  • 不要自动调用。此技能会执行不可逆的 GitHub 写入操作(合并 PR、关闭 Issue、发表评论),并且仅在显式调用时运行。
  • 不要用于在 GitHub 上应用优先级/工作量标签。优先级和规模仅在本地呈现,永远不会发布(参见安全规则)。
  • 不要用作人工最终合并决策的替代品——每次合并都会提出供明确批准,永远不会自动执行。

核心原则

  1. 写入操作需把关。 首先计算完整的分类结果,将每个拟议的写入操作(包括合并)提交审查,在用户批准之前不执行任何操作。
  2. 关闭前需有证据。 如果没有明确且引用的理由(一个已合并的 PR 或默认分支上的提交),不要关闭 Issue。当证据薄弱或模棱两可时,将 Issue 留作未完成并标记为待审查。
  3. 优先级和规模保持本地。 它们是供用户使用的内部规划辅助工具,绝不会写入 GitHub。

工作流程

阶段 0:选择目标仓库

gh auth status                       # 确认 gh 已通过身份验证
git rev-parse --is-inside-work-tree  # 当前工作目录是否是一个 git 仓库?
git remote -v                        # 列举所有远程仓库

确定远程仓库中不同的 GitHub 托管仓库的集合。当远程仓库的 URL 主机是 github.com,且为以下任一形式时,该远程仓库即为 GitHub 托管:

将每个标准化为 OWNER/REPO 并去重(一个 fork 设置可能使 origin 和 upstream 指向不同的 GitHub 仓库;指向相同 OWNER/REPO 的多个远程仓库计为一次)。

选择规则:

情况操作
恰好一个不同的 GitHub 仓库将其作为默认值——不提示用户。
不是 git 仓库,或零个 GitHub 远程仓库询问用户要分类的 OWNER/REPO。
多于一个不同的 GitHub 仓库使用 AskUserQuestion 让用户选择哪个 OWNER/REPO。

GitHub Enterprise 主机无法可靠地自动检测。如果用户使用 GHE 实例,请询问 OWNER/REPO 并让他们设置 GH_HOST / 使用 gh 配置的主机。在继续之前,将解析出的仓库向用户确认。

将结果存储为 REPO="OWNER/REPO" 并将 -R "$REPO" 传递给每个 gh 调用。在使用前根据 ^[A-Za-z0-9._-]+/[A-Za-z0-9._-]+$ 验证它,以防止恶意或格式错误的远程 URL 传入命令。

阶段 1:收集 Issue 和上下文

# 未解决的 Issue(gh issue list 默认排除 PR)
gh issue list -R "$REPO" --state open --limit 1000 \
  --json number,title,body,labels,assignees,comments,reactionGroups,createdAt,updatedAt,url

# 未解决的 PR——"待修复"(Issue 阶段)和 PR 分类(阶段 2)的候选
gh pr list -R "$REPO" --state open --limit 1000 \
  --json number,title,body,author,isDraft,reviewDecision,latestReviews,\
mergeable,mergeStateStatus,statusCheckRollup,labels,createdAt,headRefName,url,closingIssuesReferences

# 最近合并的 PR——"已解决"的候选
gh pr list -R "$REPO" --state merged --limit 300 \
  --json number,title,body,mergedAt,url,closingIssuesReferences

closingIssuesReferences 列出了 PR 链接要关闭的 Issue——通过 PR 正文中的任何 GitHub 关闭关键字(close/closes/closed、fix/fixes/fixed、resolve/resolves/resolved),或通过手动 UI 链接填充。这是可用的最强信号。对于它未涵盖的 Issue,还要在默认分支上搜索提交消息。从所选仓库权威性地解析默认分支(不从本地 origin/HEAD 解析,因为它可能未设置或指向错误的远程仓库):

default_branch=$(gh repo view "$REPO" --json defaultBranchRef --jq .defaultBranchRef.name)
# 锚定 Issue 编号,使 #12 不会匹配 #120、#123 等
git log --oneline "origin/$default_branch" \
  | grep -iE "(close|fix|resolve)[sd]? +#<N>([^0-9]|$)"

阶段 2:分类未解决的拉取请求(可选)

在 Issue 之前处理 PR:在这里合并准备好的 PR 意味着 Issue 阶段中的“已解决”检查会看到这些合并刚刚落地的工作。

如果没有未解决的 PR,则跳过此阶段。否则汇总未解决的 PR 并询问用户是否现在处理 PR(AskUserQuestion:处理 PR / 跳过到 Issue)。如果他们跳过,直接进入 Issue 分类。

根据每个未解决 PR 的审查、CI 和合并状态对其分类。下面的字段形状是 gh pr ... --json 实际返回的——依赖它们,而不是直觉:

  • 准备合并 = mergeable == "MERGEABLE" 并且 mergeStateStatus == "CLEAN" 并且 CI 未阻塞(如下)。CLEAN 是 GitHub 服务器端“无冲突、不落后、不是草稿、必需检查均通过”的裁决——任何其他 mergeStateStatus(BEHIND、UNSTABLE、BLOCKED、DIRTY、DRAFT 等)都未就绪。将 mergeable == "UNKNOWN"(GitHub 会惰性重新计算合并能力,尤其是在另一次合并之后)视为未就绪——短暂重新轮询或跳过;绝不要在此基础上合并。
  • CI 未阻塞——扫描 statusCheckRollup(以 __typename 为键)并仅在出现实际问题时拒绝该 PR:硬失败(conclusion 为 FAILURE/CANCELLED/TIMED_OUT/ACTION_REQUIRED/STARTUP_FAILURE/STALE 的 CheckRun,或 state 为 FAILURE/ERROR 的 StatusContext),或任何仍在运行的内容(status 为 QUEUED/IN_PROGRESS/WAITING/PENDING 的 CheckRun,或 state 为 PENDING/EXPECTED 的 StatusContext——等待,不要合并)。SUCCESS、NEUTRAL 和 SKIPPED 是可以的,绝不能阻塞(例如,对依赖项更新的 CodeQL 运行报告 NEUTRAL——一个通过的 Dependabot PR 使用 NEUTRAL CodeQL 检查是 CLEAN)。空汇总表示没有 CI——一种不同的状态,绝不能视为准备就绪。mergeStateStatus == "CLEAN" 已经反映了必需检查的状态;使用汇总来捕获失败/挂起的非必需检查。
  • 机器人/自动 = author.is_bot == true。根据 author.login 匹配自动合并允许列表,标准化掉 gh 的渲染——去掉前导 app/ 和后缀 [bot](gh 在某些版本中将 Dependabot 返回为 app/dependabot,在其他版本中返回为 dependabot[bot];将两者都标准化为 dependabot)。默认允许列表:dependabot、renovate,以及用户指定的任何名称。来自非允许列表机器人的通过 PR 会被报告,绝不提供合并。
  • 维护者批准 = latestReviews 有一个 state == "APPROVED" 的条目,其 authorAssociation 是 OWNER/MEMBER/COLLABORATOR,且其 author.login 不是 PR 作者。不要单独使用 reviewDecision == "APPROVED":它由分支保护驱动,并且在没有必需审查规则的仓库上为 null,因此它既过度信任(不能确认写入权限)又错过真正的批准。
  • 从未审查过 = latestReviews 没有来自 PR 作者以外的任何人的 APPROVED/CHANGES_REQUESTED 条目(fork“审查已禁用”机器人注释不算审查)。
类别条件提供的操作
可合并的机器人 PR允许列表中的机器人 + 准备就绪 + 不是草稿提供增量、按顺序合并
已批准且准备就绪维护者批准 + 准备就绪 + 不是草稿提示合并
从未审查过非机器人 + 只有作者审查过(或无审查)+ 不是草稿提供生成审查子代理
需要工作草稿、硬 CI 失败、挂起的 CI、冲突、落后、请求变更、或未准备就绪的机器人 PR仅报告——不提供操作

(“准备就绪”已包含 CI 未阻塞。审查子代理用于人类编写的 PR——未准备就绪的机器人依赖项更新报告为需要工作,不审查。)

通过 AskUserQuestion 呈现分类后的 PR 并提供适用的操作。

增量、按顺序合并(机器人 PR 和已批准且准备就绪的 PR):首先确认合并集合和合并方法(合并是不可逆的),然后一个一个地合并,最旧的优先。选择仓库允许的方法,如果仓库不允许则失败关闭:

gh repo view "$REPO" --json mergeCommitAllowed,squashMergeAllowed,rebaseMergeAllowed   # 位置参数仓库,不是 -R

对于每个 PR 按顺序,在合并前立即重新验证(每次合并后状态会漂移——一个已合并的 PR 可能会使下一个 BEHIND、冲突或正在重新计算),同步合并,然后确认它已落地再进行下一个:

gh pr view <N> -R "$REPO" --json isDraft,reviewDecision,mergeable,mergeStateStatus,statusCheckRollup
# 仅在仍在准备就绪时继续:不是草稿,mergeable == MERGEABLE,mergeStateStatus == CLEAN,CI 未阻塞
gh pr merge <N> -R "$REPO" --<method>     # 从不使用 --auto,从不使用 --admin
gh pr view <N> -R "$REPO" --json state    # 期望 "MERGED" 后再移动到下一个 PR

如果 PR 不再准备就绪(包括 mergeable == "UNKNOWN")、合并未落地、或任何必需检查未通过,则停止并报告——绝不强制、使用 --admin、--auto 或跳过检查。对于机器人 PR,在把关中公开依赖项和版本跳转(例如主要版本更新),以便用户可以在有上下文的情况下决定。

审查子代理(从未审查过的 PR):当用户选择加入时,为每个 PR 生成一个Agent——全部在一条助手消息中,以便它们并行运行。每个子代理审查一个 PR 的差异并返回结构化审查;将每个写入工作目录下的 github-pr-<number>-review.md(覆盖该 PR 的任何先前文件)。审查是只读的,从不发布到 GitHub。有关子代理提示、审查量表和文件格式,请参阅 references/reviewing-prs.md。

在任何合并之后,重新获取已合并的 PR 列表(阶段 1 的 --state merged 查询),以便 Issue 阶段可以检测这些合并解决的 Issue。

阶段 3:分类每个未解决的 Issue

将每个未解决的 Issue 排序到恰好一个桶中。

桶 A——已解决(工作已落地,Issue 仍保持开放)。 需要具体证据;优先采用相互印证而不是单个弱信号:

  • 一个合并的 PR 在 closingIssuesReferences 中列出了该 Issue,或者其标题/正文与关闭关键字一起引用了 #N。(最强。)
  • 默认分支上的一个提交使用关闭关键字引用了 #N。
  • Issue 要求的行为在当前代码中明显存在——通过使用 Grep/Read 阅读相关代码来验证,不要假设。一个不同或部分实现并不解决该 Issue。

→ 拟议的写入操作:关闭该 Issue,并附上注释,指明解决该问题的 PR/提交。

gh issue close <N> -R "$REPO" \
  -c "由 #<PR> 解决(<简短原因>)。关闭,因为更改现在位于 $default_branch 上。"

桶 B——挂起的 PR 会解决它(一个未解决的 PR 处理该 Issue)。 通过任一方向检测:未解决 PR 的 closingIssuesReferences 包含该 Issue;Issue 正文/评论链接了该 PR;或者一个未解决 PR 明确修复了 Issue 描述的相同内容。目标是使 Issue 和 PR 互相引用——只填补真正的空白,并优先使用非破坏性写入操作:

  • 任一方向都没有引用 → 在缺少引用的一方发布一个指向性注释(非破坏性)。提及 #<PR> / #<N> 会创建一个交叉引用,GitHub 会将其镜像到另一方的动态中。
    gh issue comment <N> -R "$REPO" -b "修复正在进行中,参见 #<PR>。"
    
  • 至少一个方向已链接 → 记录“已链接——无需操作”。

除非用户明确希望 PR 在合并时自动关闭该 Issue,否则不要编辑 PR 正文。注释建立了引用但不会触发自动关闭——只有 PR 正文中的关闭关键字或提交消息才会触发。当用户选择加入时,绝不破坏描述:在编辑前立即重新获取正文,并通过 stdin 传递,以便不受信任的 PR 文本永远不会经过 shell 插值字符串:

body=$(gh pr view <PR> -R "$REPO" --json body --jq .body)
printf '%s\n\nCloses #%s\n' "$body" "<N>" | gh pr edit <PR> -R "$REPO" --body-file -

不要重复已经存在的链接。

桶 C——未解决(没有解决方案,没有挂起的 PR)。 仅在本地分配优先级和变更规模评估(下一节)。

阶段 4:为未解决的 Issue 评分(仅限本地)

优先级——Critical / High / Medium / Low。权衡:

  • 影响/严重性——安全、数据丢失、崩溃或正确性错误排名高于增强功能;文档/美观排名最低。现有标签(security、bug、crash、regression)是强信号。
  • 范围——影响多少用户/工作流程。
  • 信号——反应(👍)、重复报告、带有持续活动的年龄。
  • 紧迫性——阻塞发布、有截止日期或有活动的回归。

变更规模——工作量代理,以 size/* T 恤桶的形式表示,来自估计的变更总行数(添加行 + 删除行,忽略生成/供应商文件),使用 Kubernetes/Prow 的阈值。

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

trailofbits/address-sanitizer

AddressSanitizer detects memory errors during fuzzing. Use when fuzzing C/C++ code to find buffer overflows and use-after-free bugs.

trailofbits/aflpp

AFL++ is a fork of AFL with better fuzzing performance and advanced features. Use for multi-core fuzzing of C/C++ projects.

trailofbits/agentic-actions-auditor

Audits GitHub Actions workflows for security vulnerabilities in AI agent integrations including Claude Code Action, Gemini CLI, OpenAI Codex, and GitHub AI Inference. Detects attack vectors where attacker-controlled input reaches AI agents running in CI/CD pipelines, including env var intermediary patterns, direct expression injection, dangerous sandbox configurations, and wildcard user allowlists. Use when reviewing workflow files that invoke AI coding agents, auditing CI/CD pipeline security for prompt injection risks, or evaluating agentic action configurations.

trailofbits/algorand-vulnerability-scanner

Scans Algorand smart contracts for 11 common vulnerabilities including rekeying attacks, unchecked transaction fees, missing field validations, and access control issues. Use when auditing Algorand projects (TEAL/PyTeal).

trailofbits/ask-questions-if-underspecified

Clarify requirements before implementing. Use when serious doubts arise.

trailofbits/atheris

Atheris is a coverage-guided Python fuzzer based on libFuzzer. Use for fuzzing pure Python code and Python C extensions.

trailofbits/audit-augmentation

Augments Trailmark code graphs with external audit findings from SARIF static analysis results and weAudit annotation files. Maps findings to graph nodes by file and line overlap, creates severity-based subgraphs, and enables cross-referencing findings with pre-analysis data (blast radius, taint, etc.). Use when projecting SARIF results onto a code graph, overlaying weAudit annotations, cross-referencing Semgrep or CodeQL findings with call graph data, or visualizing audit findings in the context of code structure.

trailofbits/audit-context-building

Enables ultra-granular, line-by-line code analysis to build deep architectural context before vulnerability or bug finding.

trailofbits/audit-prep-assistant

Prepares codebases for security review using Trail of Bits' checklist. Helps set review goals, runs static analysis tools, increases test coverage, removes dead code, ensures accessibility, and generates documentation (flowcharts, user stories, inline comments).

trailofbits/burpsuite-project-parser

Searches and explores Burp Suite project files (.burp) from the command line. Use when searching response headers or bodies with regex patterns, extracting security audit findings, dumping proxy history or site map data, or analyzing HTTP traffic captured in a Burp project.

trailofbits/cairo-vulnerability-scanner

Scans Cairo/StarkNet smart contracts for 6 critical vulnerabilities including felt252 arithmetic overflow, L1-L2 messaging issues, address conversion problems, and signature replay. Use when auditing StarkNet projects.

trailofbits/cargo-fuzz

cargo-fuzz is the de facto fuzzing tool for Rust projects using Cargo. Use for fuzzing Rust code with libFuzzer backend.

trailofbits/chrome-mcp-troubleshooting

Diagnose and fix Claude in Chrome MCP extension connectivity issues. Use when mcp__claude-in-chrome__* tools fail, return "Browser extension is not connected", or behave erratically.

trailofbits/claude-in-chrome-troubleshooting

Diagnose and fix Claude in Chrome MCP extension connectivity issues. Use when mcp__claude-in-chrome__* tools fail, return "Browser extension is not connected", or behave erratically.

trailofbits/code-improver

Runs an autonomous review-and-fix improvement loop over any code target — a skill, plugin, module, or directory — using a reviewer the user names: any installed skill or agent. Keeps a cross-round findings ledger, escalates when fixes stop converging, and guards scope mechanically. Use when asked to 'improve this code until review passes', 'run an improvement loop with <reviewer>', or to iterate review-and-fix with a specific reviewer. For skills prefer the skill-improver entry; for a branch prefer pr-improver.

trailofbits/code-maturity-assessor

Systematic code maturity assessment using Trail of Bits' 9-category framework. Analyzes codebase for arithmetic safety, auditing practices, access controls, complexity, decentralization, documentation, MEV risks, low-level code, and testing. Produces professional scorecard with evidence-based ratings and actionable recommendations.

trailofbits/codeql

Scans a codebase for security vulnerabilities using CodeQL's interprocedural data flow and taint tracking analysis. Triggers on "run codeql", "codeql scan", "codeql analysis", "build codeql database", or "find vulnerabilities with codeql". Supports "run all" (security-and-quality + security-experimental suites) and "important only" (high-precision security findings) scan modes. Also handles creating data extension models and processing CodeQL SARIF output.

trailofbits/constant-time-analysis

Detects timing side-channel vulnerabilities in cryptographic code. Use when implementing or reviewing crypto code, encountering division on secrets, secret-dependent branches, or constant-time programming questions in C, C++, Go, Rust, Swift, Java, Kotlin, C#, PHP, JavaScript, TypeScript, Python, or Ruby.

trailofbits/constant-time-testing

Constant-time testing detects timing side channels in cryptographic code. Use when auditing crypto implementations for timing vulnerabilities.

trailofbits/cosmos-vulnerability-scanner

Scans Cosmos SDK blockchain modules and CosmWasm contracts for consensus-critical vulnerabilities — chain halts, fund loss, state divergence. 25 core + 16 IBC + 10 EVM + 3 CosmWasm patterns. Use when auditing custom x/ modules, reviewing IBC integrations, or assessing pre-launch chain security. Updated for SDK v0.53.x.

相关技能