用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/Morrison-Lab/ai-config --skill recover-followups命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | recover-followups |
| description | Recover untracked follow-ups. |
| user-invocable | true |
| allowed-tools | ["Bash","Read"] |
The recovery counterpart to defer-issue. defer-issue files a follow-up
when you defer; this skill goes back through already-closed PRs and issues
to catch the follow-ups that were mentioned but never turned into a tracked open
issue, then offers to file them.
This is the retroactive, cross-PR sweep that the forward and single-scope skills
don't do. defer-issue files a follow-up at defer-time. post-merge checks only
the one PR that just merged. wrap-up covers only the current session.
Querying every closed PR/issue in a busy repo is slow and noisy. Default to a
bounded window and say what window you used. Let $ARGUMENTS narrow it:
N=30)--search "closed:>=2026-01-01"--label tech-debt, --milestone v2#N → just that one PR/issuegh repo view --json nameWithOwner --jq .nameWithOwner # confirm the repo
The commands below are written for GitHub/gh; step 2 also gives the
GitLab/glab equivalents for the data-pull. Steps 3–5 use GitHub field names
(stateReason, closedByPullRequestsReferences) that have direct GitLab
analogues (an MR's merged vs closed state, an issue's closing MR); adapt
them. If the matching CLI isn't installed, say so and stop, and don't hit the
raw API blind.
The follow-up promise can live in the body, a comment, or an inline review thread; fetch all three.
# Closed PRs and issues in the window
gh pr list --state closed --limit 30 --json number,title,url,closedAt,body # LIST_PRS
gh issue list --state closed --limit 30 --json number,title,url,closedAt,body # LIST_ISSUES
# Per PR: top-level comments + review summaries ...
gh pr view <N> --json number,title,url,body,comments,reviews # VIEW_PR
# ... and inline review-thread comments (NOT in `gh pr view`):
gh api repos/{owner}/{repo}/pulls/<N>/comments --jq '.[] | {user: .user.login, body, url: .html_url}' # READ_PR_REVIEW_COMMENTS
# Per issue: body + comments
gh issue view <N> --json number,title,url,body,comments # VIEW_ISSUE
GitLab equivalents (same shape):
# In GitLab, a completed MR is `merged`, NOT `closed` (which means abandoned) —
# sweep merged ones (the main follow-up source), and optionally abandoned ones:
glab mr list --merged --per-page 30 # completed MRs — primary source
glab mr list --closed --per-page 30 # abandoned MRs — optional
glab issue list --closed --per-page 30
glab mr view <N> --comments # body + discussion
glab issue view <N> --comments
# inline MR-thread notes, the glab counterpart to `gh api …/pulls/<N>/comments`
# (`:id` is glab's placeholder for the current repo's project — auto-resolved
# when run inside the repo; no numeric ID needed):
glab api "projects/:id/merge_requests/<N>/notes" --paginate
Scan the gathered text for intent-to-defer language, not just any keyword. Signal phrases:
follow-up, followup, follow updefer, deferred, leave for later, for later, down the line,
eventually, out of scopeseparate PR, separate issue, future PR, another PR, in a follow-upTODO, FIXME, we should, we'll need to, should probably,
worth doing, let's revisit, I'll open an issue, for the next release**Deferred** or **Acknowledged** heading in a
@claude/reviewer comment is the highest-value source: those are explicit
"not doing this now" decisions.A starting regex (tune per repo) — pipe the fetched bodies straight into it
(\b is GNU-only, so this avoids word boundaries for portability to BSD/macOS
grep; TODO/FIXME may over-match, which the false-positive cull below handles):
gh pr view <N> --json body,comments,reviews --jq '.body, (.comments[].body), (.reviews[].body)' \
| grep -inE "follow[- ]?up|defer|out of scope|separate (pr|issue)|future pr|another pr|for later|down the line|eventually|TODO|FIXME|we should|we'll need to|should probably|worth doing|let's revisit|i'll open an issue|leave .* later|for the next release|acknowledged" # VIEW_PR
Keep, for each hit: the source (PR/issue # + the comment's html_url), the
snippet, and a one-line suggested issue title. Discard obvious
false positives, like a TODO quoted from code under review, or a follow-up
that the same thread says was already done.
For each candidate decide whether it's already tracked:
#123, Followup: #123, a
.../issues/123 URL.) If so, check that issue — and, if closed, why it
closed:
gh issue view 123 --json number,state,stateReason,title,closedByPullRequestsReferences # VIEW_ISSUE
stateReason == "COMPLETED", or a
merged PR in closedByPullRequestsReferences, or a "fixed in #X" comment →
the work landed → tracked (drop it).stateReason == "NOT_PLANNED"
(won't-fix / duplicate) with no merged PR → the work did not land →
still untracked (keep it; a won't-fix close doesn't mean done).gh issue list --state all --search "<keywords from the snippet>" \
--json number,title,state,stateReason,url # SEARCH_ISSUES
COMPLETED → the work landed → tracked (drop
it); NOT_PLANNED → the work did not land → still untracked (keep
it).
Widening the search without widening these bullets is the same defect
one level down: a closed match falls through to "nothing matches" and
gets re-filed, which is what this whole change exists to prevent.A linked table, never a bare #N (repo policy):
| Source | Promised follow-up | Raised in | Suggested issue title |
|---|---|---|---|
| #42 | "handle nested overrides in a follow-up" | review thread | Handle nested overrides in session_env merge |
Order by confidence (explicit **Deferred** items first, fuzzy we should…
last). Add the window you swept ("last 30 closed PRs + issues") and a
Pacific-time timestamp (TZ=America/Los_Angeles date "+%Y-%m-%d %H:%M %Z"; the
explicit TZ enforces PT on a machine set to any other zone), so the user knows
the coverage and the "as of when".
If the sweep came back empty, say so plainly; don't manufacture candidates.
defer-issue)Don't auto-file a pile of issues; that breeds duplicates and noise. Present the
list, let the user pick which to file, then for each chosen one run the
defer-issue flow: it composes the issue with a Deferred from PR #X
context line and a back-reference, checks for a followup/deferred label, and
prints the new issue URL. That keeps issue-creation in one place.
defer-issue — the forward op (file at defer-time); step 6 hands off to
it to file each recovered item.post-merge — checks deferrals for the single just-merged PR;
recover-followups is the cross-PR backstop for the ones it (or no one) ever
filed.wrap-up — session-level "what's still open"; this is repo-level "what did
past sessions drop".pr-status-all — sibling whole-repo sweep, but over open PRs' review
state rather than closed items' follow-ups.TODO (e.g. one quoted from code under review) as a real
follow-up → false positives. Match intent-to-defer language.#N instead of markdown-linked PR/issue numbers.