| name | github-triage |
| description | 只读GitHub分类(适用于issues和PRs)。每个项目1个后台任务(category: quick)。分析所有开放项目并将有证据支持的报告写入/tmp/{datetime}/。每个声明都需要GitHub永久链接作为证明。永不對GitHub执行任何操作 - 无评论、无合并、无关闭、无标签。仅为报告。触发词:'triage', 'triage issues', 'triage PRs', 'github triage'。 |
GitHub 分类 — 只读分析器
只读GitHub分类协调器。获取开放的issues/PRs,进行分类,为每个项目生成1个后台`quick`子代理。每个子代理分析并写入报告文件。零GitHub变更。
架构
1个ISSUE/PR = 1个task_create = 1个quick子代理(后台)。无例外。
| 规则 | 值 |
|---|
| Category | quick |
| Execution | run_in_background=true |
| Parallelism | 所有项目同时进行 |
| Tracking | 每个项目task_create |
| Output | /tmp/{YYYYMMDD-HHmmss}/issue-{N}.md 或 pr-{N}.md |
零操作策略(绝对)
<zero_action>
子代理必须永不运行任何写入或变更GitHub状态的命令。
禁止(非详尽):
gh issue comment, gh issue close, gh issue edit, gh pr comment, gh pr merge, gh pr review, gh pr edit, gh api -X POST, gh api -X PUT, gh api -X PATCH, gh api -X DELETE
允许:
gh issue view, gh pr view, gh api(仅GET)- 读取GitHub数据
Grep, Read, Glob - 读取代码库
Write - 仅将报告写入/tmp/
git log, git show, git blame - 读取git历史(用于查找修复提交)
任何GitHub变更是严重违规。
</zero_action>
证据规则(强制)
**报告中的每个事实声明必须包含GitHub永久链接作为证明。**
永久链接是指向特定提交中特定行/范围的URL,例如:
https://github.com/{owner}/{repo}/blob/{commit_sha}/{path}#L{start}-L{end}
如何生成永久链接
- 通过Grep/Read找到相关文件和行。
- 获取当前提交SHA:
git rev-parse HEAD
- 构建:
https://github.com/{REPO}/blob/{SHA}/{filepath}#L{line}(或范围用#L{start}-L{end})
规则
- **无永久链接 = 无声明。**如果您无法用永久链接支持陈述,请改为声明"未找到证据"。
- 没有永久链接的声明明确标记为
[UNVERIFIED],权重为零。
- 指向
main/master/dev分支的永久链接不可接受 — 仅使用提交SHA。
- 对于bug分析:永久链接到有问题的代码。对于修复验证:永久链接到修复提交的diff。
阶段 0: 设置
REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
REPORT_DIR="/tmp/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$REPORT_DIR"
COMMIT_SHA=$(git rev-parse HEAD)
将REPO、REPORT_DIR和COMMIT_SHA传递给每个子代理。
阶段 1: 获取所有开放项目(已修正)
重要:body和comments字段可能包含破坏jq解析的控制字符。首先获取基本元数据,然后在子代理中获取每个项目的完整详情。
ISSUES_LIST=$(gh issue list --repo $REPO --state open --limit 500 \
--json number,title,labels,author,createdAt)
ISSUE_COUNT=$(echo "$ISSUES_LIST" | jq length)
if [ "$ISSUE_COUNT" -eq 500 ]; then
LAST_DATE=$(echo "$ISSUES_LIST" | jq -r '.[-1].createdAt')
while true; do
PAGE=$(gh issue list --repo $REPO --state open --limit 500 \
--search "created:<$LAST_DATE" \
--json number,title,labels,author,createdAt)
PAGE_COUNT=$(echo "$PAGE" | jq length)
[ "$PAGE_COUNT" -eq 0 ] && break
ISSUES_LIST=$(echo "$ISSUES_LIST" "$PAGE" | jq -s '.[0] + .[1] | unique_by(.number)')
ISSUE_COUNT=$(echo "$ISSUES_LIST" | jq length)
[ "$PAGE_COUNT" -lt 500 ] && break
LAST_DATE=$(echo "$PAGE" | jq -r '.[-1].createdAt')
done
fi
PRS_LIST=$(gh pr list --repo $REPO --state open --limit 500 \
--json number,title,labels,author,headRefName,baseRefName,isDraft,createdAt)
PR_COUNT=$(echo "$PRS_LIST" | jq length)
if [ "$PR_COUNT" -eq 500 ]; then
LAST_DATE=$(echo "$PRS_LIST" | jq -r '.[-1].createdAt')
while true; do
PAGE=$(gh pr list --repo $REPO --state open --limit 500 \
--search "created:<$LAST_DATE" \
--json number,title,labels,author,headRefName,baseRefName,isDraft,createdAt)
PAGE_COUNT=$(echo "$PAGE" | jq length)
[ "$PAGE_COUNT" -eq 0 ] && break
PRS_LIST=$(echo "$PRS_LIST" "$PAGE" | jq -s '.[0] + .[1] | unique_by(.number)')
PR_COUNT=$(echo "$PRS_LIST" | jq length)
[ "$PAGE_COUNT" -lt 500 ] && break
LAST_DATE=$(echo "$PAGE" | jq -r '.[-1].createdAt')
done
fi
echo "Total issues: $ISSUE_COUNT, Total PRs: $PR_COUNT"
大型仓库处理:
如果总项目超过50个,您必须处理所有项目。使用上面的分页代码获取每个开放的issue和PR。
不要采样或限制为50个项目 — 处理整个积压。
例如:如果有500个开放issues,生成500个子代理。如果有1000个开放PRs,生成1000个子代理。
**注意:**后台任务系统会自动排队超额任务。
阶段 2: 分类
| 类型 | 检测 |
|---|
ISSUE_QUESTION | [Question], [Discussion], ?, "how to" / "why does" / "is it possible" |
ISSUE_BUG | [Bug], Bug:, 错误消息,堆栈跟踪,意外行为 |
ISSUE_FEATURE | [Feature], [RFE], [Enhancement], Feature Request, Proposal |
ISSUE_OTHER | 其他任何 |
PR_BUGFIX | 标题以fix开头,分支包含fix//bugfix/,标签bug |
PR_OTHER | 其他所有 |
阶段 3: 生成子代理(单独的工具调用)
关键:通过单独的工具调用逐个创建任务。一次一个。永不批量或脚本。
对于每个项目,按顺序执行这些步骤:
步骤 3.1: 创建任务记录
task_create(
subject="Triage: #{number} {title}",
description="GitHub {issue|PR} triage analysis - {type}",
metadata={"type": "{ISSUE_QUESTION|ISSUE_BUG|ISSUE_FEATURE|ISSUE_OTHER|PR_BUGFIX|PR_OTHER}", "number": {number}}
)
步骤 3.2: 生成分析子代理(后台)
task(
category="quick",
run_in_background=true,
load_skills=[],
prompt=SUBAGENT_PROMPT
)
子代理的绝对规则:
- 仅分析 - 永不對GitHub采取行动(无评论、合并、关闭)
- 只读 - 仅使用读取代码/GitHub数据的工具
- 仅写报告 - 输出通过Write工具写入
{REPORT_DIR}/{issue|pr}-{number}.md
- 需要证据 - 每个声明必须有GitHub永久链接作为证明
对于每个项目:
1. task_create(subject="Triage: #{number} {title}")
2. task(category="quick", run_in_background=true, load_skills=[], prompt=SUBAGENT_PROMPT)
3. 存储映射:item_number -> { task_id, background_task_id }
子代理提示
通用前言(包含在所有子代理提示中)
CONTEXT:
- Repository: {REPO}
- Report directory: {REPORT_DIR}
- Current commit SHA: {COMMIT_SHA}
PERMALINK FORMAT:
Every factual claim MUST include a permalink: https://github.com/{REPO}/blob/{COMMIT_SHA}/{filepath}#L{start}-L{end}
No permalink = no claim. Mark unverifiable claims as [UNVERIFIED].
To get current SHA if needed: git rev-parse HEAD
ABSOLUTE RULES (violating ANY = critical failure):
- NEVER run gh issue comment, gh issue close, gh issue edit
- NEVER run gh pr comment, gh pr merge, gh pr review, gh pr edit
- NEVER run any gh command with -X POST, -X PUT, -X PATCH, -X DELETE
- NEVER run git checkout, git fetch, git pull, git switch, git worktree
- Your ONLY writable output: {REPORT_DIR}/{issue|pr}-{number}.md via the Write tool
ISSUE_QUESTION
You are analyzing issue #{number} for {REPO}.
ITEM:
- Issue #{number}: {title}
- Author: {author}
- Body: {body}
- Comments: {comments_summary}
TASK:
1. Understand the question.
2. Search the codebase (Grep, Read) for the answer.
3. For every finding, construct a permalink: https://github.com/{REPO}/blob/{COMMIT_SHA}/{path}#L{N}
4. Write report to {REPORT_DIR}/issue-{number}.md
REPORT FORMAT (write this as the file content):
# Issue #{number}: {title}
**Type:** Question | **Author:** {author} | **Created:** {createdAt}
## Question
[1-2 sentence summary]
## Findings
[Each finding with permalink proof. Example:]
- The config is parsed in [`src/config/loader.ts#L42-L58`](https://github.com/{REPO}/blob/{SHA}/src/config/loader.ts#L42-L58)
## Suggested Answer
[Draft answer with code references and permalinks]
## Confidence: [HIGH | MEDIUM | LOW]
[Reason. If LOW: what's missing]
## Recommended Action
[What maintainer should do]
---
REMEMBER: No permalink = no claim. Every code reference needs a permalink.
ISSUE_BUG
You are analyzing bug report #{number} for {REPO}.
ITEM:
- Issue #{number}: {title}
- Author: {author}
- Body: {body}
- Comments: {comments_summary}
TASK:
1. Understand: expected behavior, actual behavior, reproduction steps.
2. Search the codebase for relevant code. Trace the logic.
3. Determine verdict: CONFIRMED_BUG, NOT_A_BUG, ALREADY_FIXED, or UNCLEAR.
4. For ALREADY_FIXED: find the fixing commit using git log/git blame. Include the commit SHA and what changed.
5. For every finding, construct a permalink.
6. Write report to {REPORT_DIR}/issue-{number}.md
FINDING "ALREADY_FIXED" COMMITS:
- Use `git log --all --oneline -- {file}` to find recent changes to relevant files
- Use `git log --all --grep="fix" --grep="{keyword}" --all-match --oneline` to search commit messages
- Use `git blame {file}` to find who last changed the relevant lines
- Use `git show {commit_sha}` to verify the fix
- Construct commit permalink: https://github.com/{REPO}/commit/{fix_commit_sha}
REPORT FORMAT (write this as the file content):
# Issue #{number}: {title}
**Type:** Bug Report | **Author:** {author} | **Created:** {createdAt}
## Bug Summary
**Expected:** [what user expects]
**Actual:** [what actually happens]
**Reproduction:** [steps if provided]
## Verdict: [CONFIRMED_BUG | NOT_A_BUG | ALREADY_FIXED | UNCLEAR]
## Analysis
### Evidence
[Each piece of evidence with permalink. No permalink = mark [UNVERIFIED]]
### Root Cause (if CONFIRMED_BUG)
[Which file, which function, what goes wrong]
- Problematic code: [`{path}#L{N}`](permalink)
### Why Not A Bug (if NOT_A_BUG)
[Rigorous proof with permalinks that current behavior is correct]
### Fix Details (if ALREADY_FIXED)
- **Fixed in commit:** [`{short_sha}`](https://github.com/{REPO}/commit/{full_sha})
- **Fixed date:** {date}
- **What changed:** [description with diff permalink]
- **Fixed by:** {author}
### Blockers (if UNCLEAR)
[What prevents determination, what to investigate next]
## Severity: [LOW | MEDIUM | HIGH | CRITICAL]
## Affected Files
[List with permalinks]
## Suggested Fix (if CONFIRMED_BUG)
[Specific approach: "In {file}#L{N}, change X to Y because Z"]
## Recommended Action
[What maintainer should do]
---
CRITICAL: Claims without permalinks are worthless. If you cannot find evidence, say so explicitly rather than making unverified claims.
ISSUE_FEATURE
You are analyzing feature request #{number} for {REPO}.
ITEM:
- Issue #{number}: {title}
- Author: {author}
- Body: {body}
- Comments: {comments_summary}
TASK:
1. Understand the request.
2. Search codebase for existing (partial/full) implementations.
3. Assess feasibility.
4. Write report to {REPORT_DIR}/issue-{number}.md
REPORT FORMAT (write this as the file content):
# Issue #{number}: {title}
**Type:** Feature Request | **Author:** {author} | **Created:** {createdAt}
## Request Summary
[What the user wants]
## Existing Implementation: [YES_FULLY | YES_PARTIALLY | NO]
[If exists: where, with permalinks to the implementation]
## Feasibility: [EASY | MODERATE | HARD | ARCHITECTURAL_CHANGE]
## Relevant Files
[With permalinks]
## Implementation Notes
[Approach, pitfalls, dependencies]
## Recommended Action
[What maintainer should do]
ISSUE_OTHER
You are analyzing issue #{number} for {REPO}.
ITEM:
- Issue #{number}: {title}
- Author: {author}
- Body: {body}
- Comments: {comments_summary}
TASK: Assess and write report to {REPORT_DIR}/issue-{number}.md
REPORT FORMAT (write this as the file content):
# Issue #{number}: {title}
**Type:** [QUESTION | BUG | FEATURE | DISCUSSION | META | STALE]
**Author:** {author} | **Created:** {createdAt}
## Summary
[1-2 sentences]
## Needs Attention: [YES | NO]
## Suggested Label: [if any]
## Recommended Action: [what maintainer should do]
PR_BUGFIX
You are reviewing PR #{number} for {REPO}.
ITEM:
- PR #{number}: {title}
- Author: {author}
- Base: {baseRefName} <- Head: {headRefName}
- Draft: {isDraft} | Mergeable: {mergeable}
- Review: {reviewDecision} | CI: {statusCheckRollup_summary}
- Body: {body}
TASK:
1. Fetch PR details (READ-ONLY): gh pr view {number} --repo {REPO} --json files,reviews,comments,statusCheckRollup,reviewDecision
2. Read diff: gh api repos/{REPO}/pulls/{number}/files
3. Search codebase to verify fix correctness.
4. Write report to {REPORT_DIR}/pr-{number}.md
REPORT FORMAT (write this as the file content):
# PR #{number}: {title}
**Type:** Bugfix | **Author:** {author}
**Base:** {baseRefName} <- {headRefName} | **Draft:** {isDraft}
## Fix Summary
[What bug, how fixed - with permalinks to changed code]
## Code Review
### Correctness
[Is fix correct? Root cause addressed? Evidence with permalinks]
### Side Effects
[Risky changes, breaking changes - with permalinks if any]
### Code Quality
[Style, patterns, test coverage]
## Merge Readiness
| Check | Status |
|-------|--------|
| CI | [PASS / FAIL / PENDING] |
| Review | [APPROVED / CHANGES_REQUESTED / PENDING / NONE] |
| Mergeable | [YES / NO / CONFLICTED] |
| Draft | [YES / NO] |
| Correctness | [VERIFIED / CONCERNS / UNCLEAR] |
| Risk | [NONE / LOW / MEDIUM / HIGH] |
## Files Changed
[List with brief descriptions]
## Recommended Action: [MERGE | REQUEST_CHANGES | NEEDS_REVIEW | WAIT]
[Reasoning with evidence]
---
NEVER merge. NEVER comment. NEVER review. Write to file ONLY.
PR_OTHER
You are reviewing PR #{number} for {REPO}.
ITEM:
- PR #{number}: {title}
- Author: {author}
- Base: {baseRefName} <- Head: {headRefName}
- Draft: {isDraft} | Mergeable: {mergeable}
- Review: {reviewDecision} | CI: {statusCheckRollup_summary}
- Body: {body}
TASK:
1. Fetch PR details (READ-ONLY): gh pr view {number} --repo {REPO} --json files,reviews,comments,statusCheckRollup,reviewDecision
2. Read diff: gh api repos/{REPO}/pulls/{number}/files
3. Write report to {REPORT_DIR}/pr-{number}.md
REPORT FORMAT (write this as the file content):
# PR #{number}: {title}
**Type:** [FEATURE | REFACTOR | DOCS | CHORE | TEST | OTHER]
**Author:** {author}
**Base:** {baseRefName} <- {headRefName} | **Draft:** {isDraft}
## Summary
[2-3 sentences with permalinks to key changes]
## Status
| Check | Status |
|-------|--------|
| CI | [PASS / FAIL / PENDING] |
| Review | [APPROVED / CHANGES_REQUESTED / PENDING / NONE] |
| Mergeable | [YES / NO / CONFLICTED] |
| Risk | [LOW / MEDIUM / HIGH] |
| Alignment | [YES / NO / UNCLEAR] |
## Files Changed
[Count and key files]
## Blockers
[If any]
## Recommended Action: [MERGE | REQUEST_CHANGES | NEEDS_REVIEW | CLOSE | WAIT]
[Reasoning]
---
NEVER merge. NEVER comment. NEVER review. Write to file ONLY.
阶段 4: 收集和更新
通过background_output()轮询每个任务。完成后:
- 解析报告。
task_update(id=task_id, status="completed", description=REPORT_SUMMARY)
- 立即流式传输给用户。
阶段 5: 最终总结
写入{REPORT_DIR}/SUMMARY.md并显示给用户:
# GitHub Triage Report - {REPO}
**Date:** {date} | **Commit:** {COMMIT_SHA}
**Items Processed:** {total}
**Report Directory:** {REPORT_DIR}
## Issues ({issue_count})
| Category | Count |
|----------|-------|
| Bug Confirmed | {n} |
| Bug Already Fixed | {n} |
| Not A Bug | {n} |
| Needs Investigation | {n} |
| Question Analyzed | {n} |
| Feature Assessed | {n} |
| Other | {n} |
## PRs ({pr_count})
| Category | Count |
|----------|-------|
| Bugfix Reviewed | {n} |
| Other PR Reviewed | {n} |
## Items Requiring Attention
[Each item: number, title, verdict, 1-line summary, link to report file]
## Report Files
[All generated files with paths]
反模式
| 违反 | 严重性 |
|---|
| 任何GitHub变更(评论/关闭/合并/审查/标签/编辑) | CRITICAL |
| 声明无永久链接 | CRITICAL |
使用quick以外的category | CRITICAL |
| 将多个项目批量到一个任务中 | CRITICAL |
run_in_background=false | CRITICAL |
在PR分支上git checkout | CRITICAL |
| 没有代码库证据的猜测 | HIGH |
不将报告写入{REPORT_DIR} | HIGH |
| 在永久链接中使用分支名而不是提交SHA | HIGH |