Agent SkillsLanternOps/breeze › gh-queue

gh-queue

GitHub

管理Breeze仓库GitHub待办队列,涵盖PR、Discussion和Issue的自动检测、状态同步与审查分流。通过本地文件持久化会话状态,辅助用户高效处理积压任务。

.claude/skills/gh-queue/SKILL.md LanternOps/breeze

Trigger Scenarios

review PR triage PRs/discussions/issues check open issues what's waiting on me gh queue

Install

npx skills add LanternOps/breeze --skill gh-queue -g -y
More Options

Non-standard path

npx skills add https://github.com/LanternOps/breeze/tree/main/.claude/skills/gh-queue -g -y

Use without installing

npx skills use LanternOps/breeze@gh-queue

指定 Agent (Claude Code)

npx skills add LanternOps/breeze --skill gh-queue -a claude-code -g -y

安装 repo 全部 skill

npx skills add LanternOps/breeze --all -g -y

预览 repo 内 skill

npx skills add LanternOps/breeze --list

SKILL.md

Frontmatter
{
    "name": "gh-queue",
    "description": "Use when reviewing, triaging, or managing the incoming GitHub backlog on the Breeze repo — PRs, Discussions, AND Issues. Stateful manager with a shared queue file, contributor profiles, parallel pr-review-toolkit dispatch, GraphQL discussion recipes, comment-style conventions, and session-log bookkeeping. Auto-detects object type from the request; bare invocation triages all three. Triggers on \"review PR\", \"PR queue\", \"triage PRs\/discussions\/issues\", \"review discussions\", \"check open issues\", \"what's waiting on me\", \"gh queue\", \"repo queue\", \"review"
}

Breeze GH Queue Manager

Overview

Long-running manager for the incoming GitHub backlog on the Breeze repo (LanternOps/breeze) — across three object types: Pull Requests, Discussions, and Issues (community + Billy + any agent-authored). State persists across sessions in two co-located files:

  • queue.md — live snapshot, split into ## PRs, ## Discussions, ## Issues sections (each with waiting-on-me / in-flight / recently-closed), plus one rolling session log at the bottom.
  • contributors.md — per-contributor profiles and review heuristics (apply across all three object types — Billy's patterns show up in PRs and discussions).

Both files are gitignored (the entire .claude/skills/ tree is in .gitignore), so they're a private scratchpad that travels with the repo on this machine but doesn't leak into commits.

Outgoing items (mine) are out of scope except to track own-PRs for merge. This skill manages what needs my review/action.

Object-type selection (auto-detect, all-default)

Pick scope from the request — no explicit flag required:

  • "review PR #5" / "PR queue" / "triage PRs" → PRs only
  • "triage discussions" / "review discussions" / "discussion #968" → Discussions only
  • "any new issues" / "triage issues" / "issue #710" → Issues only
  • bare "what's waiting on me" / "/pr" / "triage the backlog" / "gh queue" → all three

When ambiguous, default to all three but lead with whatever the user named.

When to invoke

  • "What's waiting on me?" / "What's in the queue?" / "Triage the backlog"
  • "Review PR #NNN" / "Triage discussions" / "Any new issues?"
  • After a PR merges / a discussion is answered / an issue is resolved — to update queue.md
  • When a new contributor shows up — to start a profile in contributors.md
  • At the start of a session if the user asks about repo state

Workflow

1. Re-orient

Read queue.md first to load current state. Then list live state for the in-scope type(s):

# PRs
gh pr list --repo LanternOps/breeze --state open --limit 50 \
  --json number,title,author,isDraft,updatedAt,reviewDecision

# Discussions (no gh subcommand — GraphQL; one query gets last-comment author+date)
gh api graphql -f query='
{ repository(owner:"LanternOps", name:"breeze") {
    discussions(first:50, orderBy:{field:UPDATED_AT, direction:DESC}) {
      totalCount
      nodes { number title category{name} isAnswered closed updatedAt
        author{login} comments(last:1){ totalCount nodes{ author{login} createdAt } } }
} } }'

# Issues
gh issue list --repo LanternOps/breeze --state open --limit 50 \
  --json number,title,author,labels,updatedAt,comments

Cross-check against queue.md. Add anything new, mark anything closed/merged, flag drift.

Never quote the bare open-issue count as a backlog number. As of 2026-08-16 the 248 open issues are ~112 enhancement (roadmap you filed for yourself) against ~136 defects; the total moves with how fast you file features, not with how fast you fix bugs. Every open issue now carries a label, so use the views rather than the total:

# The defect list — the number that should actually trend down
gh issue list --repo LanternOps/breeze --state open --limit 200 \
  --search 'label:bug,tech-debt,ci-red'
# Roadmap — feature work; triage it, don't count it as debt
gh issue list --repo LanternOps/breeze --state open --limit 200 --label enhancement
# Waiting on someone else — sweep for stale ones each round
gh issue list --repo LanternOps/breeze --state open --search 'label:pending-author,needs-info'

An unlabeled issue is invisible to all three, so label on sight — that's what let 69 issues escape triage entirely before 2026-08-16.

Repeated --label is AND, not OR. --label bug --label tech-debt returns only issues carrying both, which for these labels is zero — a silently empty result that reads exactly like "no defects." Use --search 'label:a,b,c' (comma = OR) whenever you want any-of semantics, and sanity-check the count against --state open before believing a small number.

The universal staleness trap — "I responded but the queue memory is stale" applies to ALL THREE types. For every open item, compare the last-activity author + date against my last engagement. If someone else spoke after me with a date past my last action, I'm the blocker — read the full thread before deciding what's open. This is the single most common failure mode and it is type-agnostic:

  • PRs: reviewDecision resets from CHANGES_REQUESTEDREVIEW_REQUIRED whenever new commits land, so a PR you bounced that's since been fixed looks identical to one the author hasn't touched. For every "REQUEST CHANGES posted" PR, verify commits.last.committedDate vs the bounce date:
    for pr in <bounced PR numbers>; do
      gh pr view $pr --repo LanternOps/breeze --json title,updatedAt,reviewDecision,commits \
        | jq -r '"#\($pr): updated \(.updatedAt) | last commit \(.commits|last.committedDate) — \(.commits|last.messageHeadline)"'
    done
    
    If last commit > bounce date, it's waiting on me → re-review (Tier-1 manual; scope is bounded to the original feedback).
  • Discussions: the comments(last:1) author in the re-orient query. isAnswered=false on a Q&A I already answered = I still owe an "accept answer." Do NOT read isAnswered=null on non-Q&A categories as "open" — that field is null for Ideas/Show-and-tell by design; use last-comment author instead. (Misread this once and flagged a pile of already-closed discussions as open.)
  • Issues: last comment author + date. A reporter who replied after my last comment is waiting on me.

Drafts — isDraft=true ≠ "not on me." A draft whose body asks for early design/approach feedback ("opening for early feedback," "thoughts before I build the rest") is genuinely waiting on me. Read the body of every incoming draft before bucketing it author-blocked (missed once on #976). Respond with a design-level COMMENT review, not an approve/merge gate. The draft flag also never auto-flips on a comment-thread handoff — #859 sat 18 days bucketed "author-blocked draft" after the author had addressed every blocker and a reviewer posted "leaving the merge decision to @ToddHebebrand," because the staleness check stopped at isDraft=true. The last-activity-author rule OUTRANKS the draft flag: apply it to drafts too, every round — if the last substantive comment hands me the ball (LGTM-pending-maintainer, "no rush" posted after fixes landed), the item is 🔴 waiting-on-me regardless of draft status.

Dependabot — "will auto-rebase" is a recurring queue.md lie. Dependabot only auto-rebases trivial conflicts, NOT lockfile conflicts. For any "auto-rebase pending" PR, check commits.last.committedDate vs the note date; if stale, post @dependabot rebase explicitly, then merge sequentially (10-15s between admin-merges) so GH's mergeability recompute keeps up.

2. Triage round

Bucket every in-scope item into:

  • 🔴 Waiting on me — needs my review/answer/decision
  • 🟡 Ball in their court — author/reporter to act; note what we're waiting for
  • 🟢 Closeable — done, just needs the close action (per close rules in §5)

Verify against code before responding (load-bearing rule). When a thread claims a gap, bug, regression, or "X is broken" — read the actual code and confirm before you answer. Plausible-sounding claims are wrong often enough that posting on them unverified produces public mistakes. Two real misses came from repeating a claim instead of checking: a "security/patches ignore orgId" gap that was already fixed by #973, and a "filters are a scale regression" claim that was actually the existing page architecture. Grep/read first, then respond. A false-negative grep is also a trap — confirm with the real symbol, not a guessed string (searched query('orgId') and got zero hits when the code used query.orgId).

PR-specific tiering — don't waste subagent budget on green-on-sight

Tier 1 — fast manual scan (~30s, no subagents). gh pr diff <N> | head -150 or gh pr view <N> --json files,additions,deletions. Green-on-sight: test-only diffs, dependency bumps, explicit verifiable cleanups, trivial config mirroring an existing pattern, dated-TODO removal (verify date + grep for live consumers).

Tier 2 — parallel pr-review-toolkit subagents (only the 🟡 pile). Heuristics: touches auth/RBAC/RLS/tenant isolation; new schema/migration; diff >~200 lines or >5 files; novel subsystem; frontend PR from an AI-assisted contributor (check Dialog.tsx/runAction/helper reinvention); title makes a hard-to-skim claim. Send one message with multiple Agent tool uses, subagent_type: pr-review-toolkit:code-reviewer:

Review PR #<NUM> on LanternOps/breeze. Fetch the diff with:
  gh pr view <NUM> --repo LanternOps/breeze --json title,body,additions,deletions,files
  gh pr diff <NUM> --repo LanternOps/breeze
Context: <2-3 sentences on what it claims + prior discussion>
Focus on: correctness bugs at file:line; tenant isolation / RLS (every new tenant table needs
policies — see CLAUDE.md); whole-system coherence (does the diff match the body? does it reinvent
something?); for Billy's PRs check globally-disconnected patterns (re-implemented modals, body-sniff
vs helper — see contributors.md); comment style (bold leads, file:line, no tables).
Report under 250 words: must-fix vs nice-to-have, file:line + one-line rationale each. Do NOT post
comments — return findings as text for me to consolidate.

Consolidate findings before posting. Group must-fix vs nice. When in doubt, lean Tier 1.

Discussions & Issues — mostly manual

No subagent tiering. Read the thread, verify claims against code (§2 rule), bucket, respond. Use a subagent only for genuinely large investigations (e.g. "is this proposed feature already half-built?" — like checking whether a filter engine already exists before greenlighting a filter PR). Issues follow the github-issues skill for etiquette/lifecycle; this manager owns the queue/triage.

3. Single-item deep review

For one PR or an architectural item, skip dispatch and review directly: gh pr view/gh pr diff first, check linked issues/discussions for context, verify tenancy changes against the RLS shape table in CLAUDE.md, check Go slog calls use err.Error() (raw err serializes as {}), verify migration naming YYYY-MM-DD-<slug>.sql + same-day -a-/-b- ordering.

4. Posting

Style (from feedback_issue_comment_style memory): bold section leads (**Root cause:**, **Fix:**), file:line refs (apps/api/src/routes/devices.ts:142), commit SHAs for prior work, prose not tables, trailing status line.

Escaping (from feedback_gh_comment_escaping): \n does NOT expand in bash double-quotes — use a heredoc or a temp file. Nested backticks in inline code spans break the comment; rephrase. For long/structured comments, write the body to a temp file and pass it via -F (most robust — avoids all shell escaping):

# PR / Issue comment
gh pr review <N> --repo LanternOps/breeze --request-changes --body "$(cat <<'EOF'
**Root cause:** ...
EOF
)"
gh issue comment <N> --repo LanternOps/breeze --body "$(cat <<'EOF' ... EOF)"

# Discussion comment — GraphQL mutation, body from a temp file
DID=$(gh api graphql -f query='{repository(owner:"LanternOps",name:"breeze"){discussion(number:<N>){id}}}' --jq '.data.repository.discussion.id')
gh api graphql -f query='mutation($id:ID!,$body:String!){addDiscussionComment(input:{discussionId:$id,body:$body}){comment{url}}}' \
  -f id="$DID" -F body=@/tmp/comment.md --jq '.data.addDiscussionComment.comment.url'

Handles (from feedback_never_invent_github_handles): NEVER @-mention a handle you didn't see verbatim in the thread. Verify with gh issue view --json author,comments / the discussion query first.

Cite docs by PUBLISHED URL, code by repo path. file:line is the right currency for code — a reader can find apps/api/src/config/validate.ts:1198 on GitHub. It is the wrong currency for documentation: apps/docs/src/content/docs/deploy/upgrades.mdx:326 is unusable to the self-hoster who asked. That tree publishes to https://docs.breezermm.com, mapping apps/docs/src/content/docs/<path>.mdxhttps://docs.breezermm.com/<path>/ (Starlight, site set in apps/docs/astro.config.*, no base). Link the page, not the source file, and curl each URL for a 200 before posting — a dead link in a public answer is worse than a repo path. Repo docs outside that tree (docs/operations/*.md, docs/registers/*.md) are not published; name them as repo files and say so. Internal issues we file for ourselves are the exception — a dev fixing backup.mdx wants the file path.

Always verify the post landed (count comments / re-read last comment). The discussion mutation can succeed while a follow-up verify query errors on a missing-first/last pagination boundary — that's a query bug, not a post failure; check before re-posting or you'll double-comment (happened on #982; deleted the dup via deleteDiscussionComment(input:{id:"DC_..."})).

5. Closing — rules differ by type

  • PRs: admin-squash-merge is the repo-owner workflow — gh pr merge <N> --repo LanternOps/breeze --squash --admin (merge commits disabled; branch protection bypassed when CI green, per CLAUDE.md).
  • Discussions: I can close my own. Comment first, then close with a reason:
    gh api graphql -f query='mutation($id:ID!){closeDiscussion(input:{discussionId:$id,reason:RESOLVED}){discussion{number closed}}}' -f id="$DID"
    
    reason: RESOLVED for answered/shipped, OUTDATED for superseded. Leave open anything with genuine outstanding work even if I wrote "closing as resolved" earlier — verify the work actually shipped (e.g. a discussion whose prerequisite PR merged but whose feature PR never did → stays open).
  • Issues: defer to the github-issues skill, which splits the rule by who filed it. NEVER close community issues yourself — reporter verifies and closes, or owner closes after reporter confirms, or owner closes stale ones with a note. A commit/deploy is not a verification. Internally-filed issues are the opposite: close them once their fix is merged, since no third party is waiting to verify.

Fixed-but-open sweep. Because PRs historically used Refs #N rather than Closes #N, merged fixes do not close their issue. When the open count looks wrong, run the sweep rather than reading titles:

gh issue list --state open --limit 400 --json number --jq '.[].number' > /tmp/open.txt
git log origin/main --since=<date> --pretty=format:'%H%x09%s%x0a%b%x00' > /tmp/log.txt
# match each open number against every commit subject+body; a subject of the form
# `fix(scope): summary (#ISSUE) (#PR)` is the repo's fully-fixed signature

Then read the commit body before closing, not the subject: several deliberately say "this is half of #N" or "leaving open for the reporter". Close only the ones with no such caveat, and comment with the fixing PR + SHA.

6. After every action

Update queue.md:

  • Move closed/merged items out of the waiting section of the right type (## PRs / ## Discussions / ## Issues)
  • Add a one-line entry to the session log at the bottom with today's absolute date (### 2026-05-30 — ...), never "today"/"yesterday"
  • If you learned a contributor pattern, update contributors.md

Adding a new contributor

When an item arrives from someone not in contributors.md: skim their first few PRs/issues (gh search prs --author <handle> --repo LanternOps/breeze), and after 2-3 interactions add a 4-6 line profile (real name + handle, AI-assisted/human/mixed, recurring patterns at file:line, response style). The point is "what to check first when their next item lands." Profiles apply across PRs, discussions, and issues.

Common gh commands

# PRs waiting on me / drafts / single PR
gh pr list --repo LanternOps/breeze --state open --search "review-requested:@me" --limit 20
gh pr list --repo LanternOps/breeze --state open --draft --limit 20
gh pr view <N> --repo LanternOps/breeze --comments

# Discussions (all via GraphQL — see §1 list query and §4/§5 mutations)
gh api graphql -f query='{repository(owner:"LanternOps",name:"breeze"){discussion(number:<N>){id title body closed comments(first:30){nodes{author{login} createdAt body}}}}}'

# Issues
gh issue list --repo LanternOps/breeze --state open --limit 50
gh issue view <N> --repo LanternOps/breeze --comments --json title,body,comments,author,labels

# Author history
gh search prs --author <handle> --repo LanternOps/breeze --limit 20

# Merge (admin bypass — repo owner workflow)
gh pr merge <N> --repo LanternOps/breeze --squash --admin

Defers to (not duplicated here)

  • pr-review-toolkit:code-reviewer — deep PR code review (Tier 2 dispatch)
  • github-issues — issue etiquette, lifecycle, issue-body templates, the never-close-community-issues rule

Related memories

  • feedback_issue_comment_style — bold leads, file:line refs, prose not tables
  • feedback_gh_comment_escaping — heredoc/temp-file for newlines, no nested backticks
  • feedback_never_invent_github_handles — only @-mention what's verbatim in the thread
  • feedback_verify_own_closes_keywordsCloses #X #Y only auto-closes #X; grep the merged diff per claimed item

Out of scope

  • Outgoing PRs (mine) beyond merge-tracking — use TodoWrite per session
  • Project-wide code-review conventions — pr-review-toolkit:code-reviewer owns those

Version History

  • 0ee1815 Current 2026-08-28 19:50

    新增文档引用规范,要求使用已发布URL而非源码路径;修复因工作区丢失风险而提交的未提交文档记录。

  • 10bb1af 2026-08-20 08:50

Same Skill Collection

.claude/skills/agent-info/SKILL.md
.claude/skills/agent-log-debugging/SKILL.md
.claude/skills/ai-agent/SKILL.md
.claude/skills/breeze-helper/SKILL.md
.claude/skills/breeze-testing/SKILL.md
.claude/skills/e2e-coverage/SKILL.md
.claude/skills/feature-testing/SKILL.md
.claude/skills/issue-to-pr/SKILL.md
.claude/skills/security-review/SKILL.md
.claude/skills/worktree-stack/SKILL.md
.claude/skills/ui-qa-sweep/SKILL.md

Metadata

Files
0
Version
0ee1815
Hash
f3fa4b28
Indexed
2026-08-20 08:50

inicio - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-09-16 17:41
浙ICP备14020137号-1