关于 pr-gardening
用于发现并跟踪近期由 Paperclip 实例创建的 Pull Request,并检查当前提交的就绪状态。该技能可协调后续准备任务并发布报告,同时保持 GitHub 只读,禁止合并、批准或关闭操作。
主要功能
- 01发现符合范围的 Pull Request
- 02检查当前提交的就绪状态
- 03派发并去重准备任务
- 04在来源 issue 中留言
- 05生成并发布就绪报告
- 06可选归档符合条件的收件箱 issue
适用场景
- 01检查近期由实例创建的 Pull Request
- 02找出检查失败或长期未更新的 PR
- 03协调后续准备工作
- 04不执行合并或批准地报告就绪情况
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ paperclipai/ paperclip --skill pr-gardening安装后在 Claude Code 中输入/pr-gardening确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
scripts/check-readiness.mjsfind-candidates.mjslib.mjspr-gardening.test.mjsrender-report.mjs详细介绍
PR 整理
主动整理 此 Paperclip 实例开启的拉取请求,这些请求在近期时间窗口内(默认为 14 天)被活跃的 Paperclip 问题提及。候选项发现和就绪状态检查由脚本完成,不进行 LLM 分析。整个工作流中,GitHub 访问始终为只读。
范围 — 仅处理我们的 PR
默认情况下,此工作流只整理由此实例的 GitHub 身份(gh 已认证的登录名,例如 cryppadotta)创建的拉取请求。社区贡献和 dependabot PR 会在 Stage A 中按作者登录名以机械方式排除,并记录在 droppedCommunityPullRequests 中;不得手动重新纳入。只有调用方明确传入 --authors 或 --include-community 时,才可以扩大范围。
严格限制
- 绝不合并、批准或关闭拉取请求。
- 绝不指示其他人员或 Agent 合并、批准或关闭拉取请求。
- 绝不整理或评论社区 PR,也绝不对其运行
/prepare-paperclip-pr。 只有 Stage A 作者允许列表中的 PR 才可操作。 - 绝不使用会更改状态的
gh命令或会更改状态的 GitHub API 请求。脚本只使用gh pr view和只读gh apiGET 请求。 - 草稿拉取请求仅作报告。不要对草稿发布整理评论。
- 只对现有的源问题发表评论。绝不为每个拉取请求创建整理问题。
--dry-run会禁止所有 Paperclip 状态变更,包括整理评论、准备任务和收件箱归档。任何模式下,发现和 GitHub 检查都保持只读。
输入
--days <N>:活动时间窗口,默认为14。同时适用于提及问题的活动时间和 PR 自身的updatedAt;窗口内没有活动的开放 PR 会作为过时项移除。--authors <logins>:以逗号分隔的 GitHub 登录名,指定纳入范围的 PR 作者;默认使用gh已认证的用户。--include-community:完全禁用作者筛选。仅在调用方明确请求时使用。--repo <owner/repo>:GitHub 仓库,默认通过gh repo view检测。--dry-run:发现、验证并生成报告,但不发布评论、不创建准备任务,也不归档收件箱条目。--archive-inbox:GitHub 确认候选 PR 已在当前头部提交版本合并后,在 Stage D 中将源问题从负责用户的收件箱中归档。--cooldown-hours <N>:重复整理的冷却时间,默认为48。--max-rounds <N>:每个 PR 的最大整理轮数,默认为3。
使用由本次运行专属的目录保存生成文件,例如 $PAPERCLIP_RUN_SCRATCH_DIR/pr-gardening。
Stage A — 发现候选项
运行提取搜索流程。它会扫描每一页结果,规范化 PR URL,按 PR 编号去重,记录每个提及该 PR 的问题,检查问题产物以识别源问题,移除 GitHub 显示为已合并或已关闭的 PR,将作者不在允许列表中的 PR(社区贡献)移至 droppedCommunityPullRequests,并将自身 updatedAt 早于时间窗口的开放 PR 移至 droppedStalePullRequests。如果问题超过每个问题的提取匹配数上限(通常是列出数百个 PR URL 的摘要或 QA 问题),则记录到 source.truncatedIssues,并在报告中注明,而不是中止运行。
node .agents/skills/pr-gardening/scripts/find-candidates.mjs \
--days 14 \
--dry-run \
--output "$RUN_DIR/candidates.json"
脚本会调用 GET /api/companies/:companyId/search/extract,并设置 kind=url、scope=all 和 updatedWithin=<N>d,然后除非 --authors 或 --include-community 覆盖设置,否则会通过 gh api user 解析作者允许列表。不要将其替换为完整的问题列表抓取或 LLM 扫描。
阶段 B — 验证当前头部提交的就绪状态
node .agents/skills/pr-gardening/scripts/check-readiness.mjs \
--input "$RUN_DIR/candidates.json" \
--output "$RUN_DIR/readiness.json" \
--dry-run
对于每个候选项,脚本都会重新获取当前头部提交的 SHA 并记录:
- 开启/草稿状态以及可合并性/冲突;
statusCheckRollup检查运行和旧版状态清单;- 在确切头部提交上已完成的 Greptile 检查运行,仅当状态为
success或neutral时才视为通过; reviewDecision;- 落后于基分支的提交数。
判定结果为 ready、needs_gardening,或草稿对应的 report_only。任何唤醒 PR 或声称已修复 PR 后,都要重新运行此阶段。切勿将 issue 评论当作就绪证明。
后续创建 PR 任务去重
如果整理工作判定某个分支需要创建后续任务来发起单个拉取请求,请先去重,再创建任何内容。
对每个分支,一次处理一个分支,并按顺序执行以下操作:
- 搜索状态为
backlog、todo、in_progress、in_review和blocked的未关闭 Paperclip issue,查找名称与分支完全匹配的 issue。 - 检查匹配 issue 的标题、描述和近期评论,确认是否已存在针对同一分支的等效未关闭“从此分支创建 PR”任务。
- 如果存在等效的未关闭任务,请复用该任务:添加简洁评论,说明当前 PR/头部提交/原因背景,并在整理 issue 或阻塞项列表中链接该任务。不要创建其他任务。
- 只有在不存在等效的未关闭任务时,才为该分支创建一个后续任务。
切勿并行批量创建后续任务。不要并发调用 POST /api/companies/:companyId/issues 来创建 create-PR 或 prepare-PR 任务。P1 的 issue 创建幂等支持可用后,每个 create-PR 后续任务的创建都必须包含 idempotencyKey: "pr-gardening:create-pr:{branch}",每个 prepare-PR 任务都必须包含 idempotencyKey: "pr-gardening:prepare-pr:{owner/repo}#{number}"。
阶段 C — 使用 /prepare-paperclip-pr 推进我们的 PR,直到就绪
在 --dry-run 模式下,以及对于 ready 或 report_only 条目,跳过此阶段。
此处每个 needs_gardening PR 都由此实例发起(阶段 A 可确保这一点),因此不要只汇报,而要主动运行 /prepare-paperclip-pr 技能,使其达到可合并状态。每次处理一个 PR:
-
冷却期和轮次。 从
candidates.json中找到originatingIssue(选择优先级:带有确切 PR URL、且工作产品类型为pull_request的 issue;然后是评论中提到该 PR 的 issue;最后是最近活跃的提及该 PR 的 issue)。获取其评论,并搜索以下标记:如果最新匹配标记距今未超过冷却期,则跳过该 PR。根据匹配标记跟踪轮次;三轮后停止,并报告
not converging; recommend close or human decision。这是建议由人工决定如何处置,并非要求关闭 PR。 -
去重。 搜索包含 PR 编号/分支的未关闭 Paperclip issue。如果已存在等效的未关闭 prepare-PR 任务,请复用该任务并添加简洁状态评论,而不要创建其他任务(见上文的去重部分)。
-
运行准备技能。 为每个 PR 创建一个专注的子任务,分配给编码 Agent(优先选择 CodexCoder),指示其针对该 PR 运行
/prepare-paperclip-pr——包括 PR URL、分支、当前头部提交 SHA,以及从readiness.json精确复制的机器检测reasons[]。如果你是整理者,且已在工作树中检出该 PR 的分支,则可以直接运行/prepare-paperclip-pr,而不是委派。无论哪种方式,准备工作都绝不能合并、批准或关闭 PR。 -
留下标记评论。 在源 issue 上发表评论,包含上述标记、当前头部提交 SHA、复制的
reasons[]、轮次计数器,以及准备任务的链接。使用POST /api/issues/:issueId/comments和X-Paperclip-Run-Id。如果 issue 已处于终止状态,请包含resume: true,以便评论创建一个可继续执行的后续任务。
建议的正文:
Gardening: dispatched `/prepare-paperclip-pr` for https://github.com/paperclipai/paperclip/pull/1234 via PAP-XXXX.
Current-head verification at `abc123` found:
- failing check: test
- Greptile missing at current head
Gardening round 1/3. Re-verification is required after changes; do not merge based on this comment.
阶段 D — 可选的收件箱整理
仅当调用方明确提供了 --archive-inbox 时才运行此阶段。即使同时提供了 --archive-inbox,--dry-run 也始终会禁止修改收件箱。未提供该标志时,不要归档任何内容。
阶段 D 适用于先前受监控且已转为已合并状态的候选项。在此阶段前立即重新运行阶段 B,并要求 GitHub 报告同一当前 head SHA 的 state: merged,该 SHA 必须与此次验证记录的 SHA 相同。阶段 A 的全新发现会有意排除已合并或已关闭的 PR。
对于每个符合条件的候选项,使用 POST /api/issues/:issueId/inbox-archive 和空 JSON 请求体,将其 originatingIssue 从负责用户的收件箱中归档。不要传递 userId;Paperclip API 会根据 gardener 的运行上下文解析负责用户,并强制执行该用户的收件箱 Agent 策略。GitHub 访问仍保持只读。
不要归档仅处于 ready 状态、未合并即关闭、处于草稿状态、待处理,或在未经验证或过时的 head 上已合并的 PR。用户仍在等待对相关问题进行审查、决策、批准或其他操作时,绝不要归档其来源问题。如果 Paperclip 因无法确定负责用户、收件箱管理已禁用、gardener 不在允许列表中或适用信任边界而拒绝修改,请报告拒绝情况,并继续执行,不要尝试绕过策略重试。
归档成功后,在来源问题上留下标准的园艺标记评论,注明已归档的问题和已合并的 PR:
Inbox tidy-up: archived [PAP-310](/PAP/issues/PAP-310) from the responsible user's inbox after confirming https://github.com/paperclipai/paperclip/pull/1234 merged at current head `abc123`.
This archive is audited and reversible; later issue activity may resurface the item.
使用 POST /api/issues/:issueId/comments,并在归档和评论请求中都包含 X-Paperclip-Run-Id。在 --dry-run 模式下,报告将要执行的归档操作和将要写入的标记评论,但不执行任何修改。
阶段 E — 监控直至终止
将园艺运行问题的 blockedByIssueIds 设置为阶段 C 中尚未终止的准备任务和已处理的来源问题,这样阻塞项解除后就会唤醒 gardener。定时或手动重新运行作为备用方案。
每次唤醒时,首先重新运行阶段 B。只有在机械验证到以下任一情况时,PR 才会从主动园艺处理中终止:
- 已在当前 head 上验证为
ready; - 已在外部合并或关闭;
- 已达到最大轮数,并报告为未能收敛。
不要让园艺问题被终止问题阻塞。不要轮询 Agent 或长时间运行的会话。
阶段 F — 生成并发布报告
node .agents/skills/pr-gardening/scripts/render-report.mjs \
--input "$RUN_DIR/readiness.json" \
--output "$RUN_DIR/gardening-report.md"
报告应说明范围(作者 + 时间窗口),并为每个未关闭的 PR 提供其作者、取自 PR 描述的一行用途摘要,以及就绪信心等级:
- 高: 当前 head 的检查通过、无冲突、Greptile 检查干净、基准分支为最新状态、来源问题已终止。
- 中: 其他方面均通过,但基准分支过时、审查尚未完成,或来源问题仍处于活动状态。
- 低: 检查失败或待处理、缺少 Greptile、处于草稿/刚修复但未验证状态,或无法识别来源问题。
如果 PR 生成的用途说明为空或没有帮助,发布报告时应根据 PR 标题和 diff 摘要写一句描述。
将 candidates.json、readiness.json 和 gardening-report.md 上传到园艺问题,使用 Markdown 正文创建或更新 gardening-report 问题文档,并留下带有工件链接的摘要评论。报告是交付物;它绝不代表合并授权。
验证
运行有针对性的脚本测试:
node --test .agents/skills/pr-gardening/scripts/pr-gardening.test.mjs
对于实时试运行,使用 --dry-run 执行阶段 A、B 和 F,然后仅在指定 PR 仍处于未关闭状态时对其进行合理性检查。已合并或已关闭的示例应出现在 droppedClosedPullRequests 中,而不是就绪结果中;由社区作者提交的 PR 必须仅出现在 droppedCommunityPullRequests 中——作者不在允许列表中的候选项或报告条目都属于范围错误。如果还要测试 --archive-inbox,请确认报告说明了阶段 D 中被抑制的操作,并且没有发生 Paperclip 归档或标记评论修改。