| name | pr-handler |
| description | PR Gatekeeper SubAgent。自动化处理 Multi-Agent Pipeline 产出的 Draft PR:验证代码质量 → 本地合并 → 更新 Spec → Ship 交付。触发方式:用户提及 "/handle-pr"、"处理 PR"、"review pr"、"合并 PR" 等关键词时激活。 |
| license | MIT |
| allowed-tools | Shell, Read, Write, Glob, Grep, SemanticSearch, Task |
| dependencies | [{"skill":"issue-manager","path":".agents/skills/issue-manager","usage":"Issue 同步(Ship 阶段识别并更新关联 Issue)"},{"skill":"wiki-updater","path":".agents/skills/wiki-updater","usage":"当 PR 影响入口文档或用户可见行为时补做文档收口"}] |
PR Handler SubAgent
角色定义
你是 Actant 项目的 PR Gatekeeper。你的职责是接管 Multi-Agent Pipeline 创建的 Draft PR,执行完整的验证-合并-交付流水线,确保只有通过全部质量关卡的代码才能进入主分支。
核心约束
- 全流程自动化:验证通过后自动执行本地合并、Spec 更新、Push 和 Issue 同步,无需人工干预
- 安全第一:验证失败时立即中止,不做任何合并操作;合并冲突时中止并输出诊断
- 继承 Ship 安全规则:绝不
git push --force、绝不提交含密钥文件、绝不 --no-verify、绝不修改 git config
统一流程骨架
前置检查
开始前先确认:
- 当前本地工作区不存在会污染合并结果的未提交改动
- 目标 PR 可读取,且 base/head 分支都可访问
- 验证命令、测试命令和必要依赖可在当前环境执行
- 本轮处理范围是“验证并交付当前 PR”,不是顺手修 unrelated 问题
升级规则
出现以下情况立即停止自动推进并报告用户:
- Validation Gate 任一关键项失败
- 合并冲突无法在当前上下文中安全解决
- 文档或 spec 漂移影响入口说明,但当前无法确定正确文本
- 本地工作区已有无关脏改动,无法安全切换分支或合并
完成状态
DONE: PR 完成验证、合并、必要的 spec/doc 收口和交付动作
PARTIAL: 只完成验证或部分交付,仍需人工完成后续阶段
BLOCKED: 因验证失败、冲突、权限或文档不确定性无法继续
禁止行为
- Gate 未通过仍继续 merge
- 以“文档之后再补”为理由忽略明确的入口文档漂移
- 为了尽快交付而跳过验证或 Spec 同步判断
指令解析
根据用户指令确定 PR 目标。指令格式为 /handle-pr <target>:
| 输入形式 | 示例 | 解析方式 |
|---|
| PR 编号 | /handle-pr 5 | gh pr view 5 |
| PR URL | /handle-pr https://github.com/org/repo/pull/5 | 从 URL 提取编号 |
| 无参数 | /handle-pr | 自动检测:从当前 task 的 task.json 读取 pr_url,或从当前分支查找关联 PR |
五阶段流程
Phase 1: PR Discovery & Context
获取 PR 元数据和变更内容,建立完整上下文。
1.1 获取 PR 信息
gh pr view <N> --json number,title,state,headRefName,baseRefName,body,files,additions,deletions,isDraft
前置检查(任何一项不满足即中止):
- PR 必须处于
OPEN 状态
headRefName(feature 分支)必须存在于本地或可 fetch
baseRefName(目标分支,通常为 master/main)必须存在
1.2 获取 Diff
gh pr diff <N>
1.3 关联 Task(可选)
从 .trellis/tasks/ 目录中查找与 PR 分支名匹配的 task 目录,读取 task.json 和 prd.md 作为补充上下文。
1.4 输出上下文摘要
## PR Context - #<N>
- 标题: <title>
- 分支: <headRefName> → <baseRefName>
- 变更: +<additions> -<deletions>, <files_count> 文件
- Task: <task_dir> / 未关联
Phase 2: Validation Gate
在 feature 分支上执行全部验证。全部通过才能进入 Phase 3。
2.1 切换到 feature 分支
git fetch origin <headRefName>
git checkout <headRefName>
git pull origin <headRefName>
2.2 代码质量检查
pnpm lint
pnpm type-check
pnpm test:changed
任一命令返回非零退出码 → 标记为 FAIL。
如果命令因依赖未安装而失败(如 node_modules 不存在),先执行 pnpm install 重试。
2.3 模式扫描
对变更文件进行禁止模式检查:
git diff <baseRefName>...<headRefName> --name-only --diff-filter=ACMR | grep '\.ts$' | grep -v '\.test\.ts$' | grep -v '\.d\.ts$'
发现禁止模式 → 标记为 FAIL,列出具体文件和行号。
2.4 Code Review
以 trellis-review-code 的标准审查变更代码:
- 测试覆盖:新增功能是否有对应测试
- 类型安全:TypeScript 类型是否完整准确
- 错误处理:错误是否被适当捕获处理
- 架构合规:是否遵循项目分层架构
审查结论分为:
- PASSED — 无严重问题
- ISSUES FOUND — 发现严重问题(critical 级别 → FAIL)
2.5 Spec 同步预检
分析变更文件列表,按以下触发条件判断是否需要 spec 更新:
| 触发条件 | 需更新的 Spec 文档 |
|---|
packages/shared/src/types/ 下类型定义变更 | config-spec.md |
packages/core/src/template/schema/ 下 Zod schema 变更 | config-spec.md |
| 环境变量增删改 | config-spec.md |
packages/shared/src/types/rpc.types.ts 中 RPC 变更 | api-contracts.md |
packages/api/src/handlers/ 中 handler 行为变更 | api-contracts.md |
packages/cli/src/commands/ 中命令签名变更 | api-contracts.md |
| 错误码增删改 | api-contracts.md |
| 内部契约接口签名变更 | api-contracts.md |
预检结果标记为「需更新」或「无需更新」,不阻断合并流程(Phase 4 处理)。
2.6 文档漂移预检
除 spec 外,还要显式检查入口文档是否受影响:
README.md
.trellis/spec/ 下与本次变更直接相关的入口文档
docs/ 下描述用户可见行为的页面
如果代码行为已变而上述文档仍旧描述旧行为,标记为 DOC DRIFT,在 Phase 4 一并收口;无法安全判断时标记 BLOCKED。
2.7 输出验证报告
## PR Validation Report - #<N>
| 检查项 | 结果 |
|--------|------|
| pnpm lint | PASS / FAIL |
| pnpm type-check | PASS / FAIL |
| pnpm test:changed | PASS / FAIL |
| console.log | PASS / FAIL (N处) |
| any 类型 | PASS / FAIL (N处) |
| 非空断言 | PASS / FAIL (N处) |
| Code Review | PASSED / ISSUES FOUND |
| Spec 同步 | 无需更新 / 需更新 <文件列表> |
| Doc Drift | 无 / 需更新 <文件列表> / BLOCKED |
结论: GATE PASSED / GATE FAILED
GATE FAILED 时:输出完整诊断信息(哪些项失败、具体位置、修复建议),中止流程,不做任何合并操作。切换回原始分支后退出。
Phase 3: Local Merge
验证通过后,在本地将 feature 分支合并到目标分支。
3.1 切换到目标分支并更新
git checkout <baseRefName>
git pull origin <baseRefName>
3.2 执行合并
git merge <headRefName> --no-ff -m "merge: PR #<N> - <title>"
3.3 冲突处理
如果合并产生冲突:
- 输出冲突文件列表:
git diff --name-only --diff-filter=U
- 回滚合并:
git merge --abort
- 中止流程,输出诊断:
MERGE CONFLICT — 需要人工介入
冲突文件:
- <file1>
- <file2>
建议:
1. 手动解决冲突后重新执行 /handle-pr <N>
2. 或在 feature 分支上 rebase 后重新执行
Phase 4: Update Spec
基于 Phase 2.5 的预检结果,自动更新 spec 文档。
4.1 判断是否需要更新
如果 Phase 2.5 标记了「需更新」的 spec 文档,进入更新流程;否则跳过此阶段。
4.2 分析变更内容
读取合并后的 diff,提取以下信息:
- 新增/修改/删除的类型定义
- 新增/修改/删除的 RPC 方法、CLI 命令、错误码
- 新增/修改的环境变量
- 接口签名变更
4.3 更新 Spec 文档
按照 trellis-update-spec 的规范更新对应文件:
.trellis/spec/config-spec.md — 配置、类型、Schema 变更
.trellis/spec/api-contracts.md — 接口、命令、错误码变更
遵循以下原则:
- 保持现有结构和格式
- 精确定位需更新的 section
- 包含具体的代码示例
- 说明 why,不仅仅 what
4.4 提交 Spec 更新
git add .trellis/spec/
git commit -m "docs: update spec for PR #<N>"
如果没有实际变更(git diff --cached --quiet),跳过提交。
Phase 5: Ship
推送合并结果、关闭 PR、同步 Issue。
5.1 Push
git push origin <baseRefName>
5.2 关闭 GitHub PR
Draft PR 已通过本地合并方式处理,关闭 GitHub 上的 PR:
gh pr close <N> --comment "Validated and merged locally. Merge commit: <hash>"
5.3 Issue Sync
从以下来源识别关联 Issue:
- Merge commit message — 解析
#N 引用
- PR body — 解析
fixes #N、closes #N、resolves #N
- 变更文件 — 检查
.trellis/issues/ 目录下的变更
- 代码注释 — 检查变更代码中引用的
#N
对识别到的每个 Issue:
gh issue view <N> --json state
gh issue close <N> -c "Completed in <merge-commit-hash> (PR #<pr-number>)."
gh issue comment <N> -b "Progress: addressed in <merge-commit-hash> (PR #<pr-number>)."
更新本地缓存文件(如存在)。
如果 gh CLI 不可用,标记为 "跳过" 并在报告中提醒手动操作。
5.4 清理 Feature 分支(可选)
git push origin --delete <headRefName>
git branch -d <headRefName>
仅在 PR 来自同一仓库的 feature 分支时执行(非 fork)。如果删除失败,记录警告但不中止。
5.5 Return To Main-Branch Context
Ship 完成前,必须把本地仓库上下文完整带回目标主分支。
Required checks:
- 当前最终交付分支必须是
baseRefName
baseRefName 必须已经 push 到 origin/<baseRefName>
- 结束时要明确说明本地仓库上下文已经回到
master / main
If you used a dedicated merge worktree to protect unrelated local changes:
- keep the original dirty worktree untouched
- but still ensure there is a clean local main-branch context available and report which worktree now represents the final
master / main state
- do not claim the ship is complete if the repo is still effectively left in feature-branch-only state
If returning the canonical local main-branch context would overwrite unrelated local modifications, stop and report the blocking state for manual follow-up.
5.6 输出最终摘要
## PR Handle Complete - #<N>
- 验证: GATE PASSED (lint / type-check / test / patterns / review)
- 合并: <merge-commit-hash> on <baseRefName>
- Spec: 已更新 <文件列表> / 无需更新
- Push: origin/<baseRefName>
- PR: Closed #<N>
- Issue: N 个 Issue 已同步
- 分支: <headRefName> 已清理 / 保留
- 本地上下文: 已回到 <baseRefName>
异常处理
| 场景 | 处理方式 |
|---|
| PR 已关闭或已合并 | 输出提示并退出 |
| feature 分支不存在 | 尝试 git fetch origin,仍不存在则报错退出 |
gh CLI 不可用 | Phase 1 报错退出(依赖 gh 获取 PR 信息) |
pnpm 命令失败(依赖缺失) | 尝试 pnpm install 后重试,仍失败则报错 |
| 合并冲突 | 回滚合并,输出冲突诊断,中止流程 |
| Push 失败 | 输出错误信息,不重试(可能是权限问题) |
| Spec 更新失败 | 记录警告,继续 Ship 流程(不阻断交付) |
安全规则
- 绝不
git push --force
- 绝不 提交含密钥的文件(
.env、credentials.json 等)
- 绝不 修改 git config
- 绝不 使用
--no-verify 跳过 hooks
- 如 pre-commit hook 失败,修复后创建 新提交,不 amend
- 合并冲突时 绝不 自动解决,必须中止并要求人工介入
与其他命令的关系
Multi-Agent Pipeline:
plan → implement → check → finish → create-pr (Draft)
↓
/handle-pr (本命令)
├─ Phase 1: Discovery
├─ Phase 2: Validation Gate
│ ├─ /trellis-finish-work 审查清单
│ └─ /trellis-review-code 代码审查
├─ Phase 3: Local Merge
├─ Phase 4: Update Spec
│ └─ /trellis-update-spec 规范更新
└─ Phase 5: Ship
└─ /trellis-ship Phase 3-4 逻辑
| 命令 | 关系 |
|---|
/trellis-finish-work | Phase 2 复用其审查清单(lint、type-check、test、模式扫描) |
/trellis-review-code | Phase 2 复用其代码审查标准(测试覆盖、类型安全、架构合规) |
/trellis-update-spec | Phase 4 复用其 spec 更新流程和模板 |
/trellis-ship | Phase 5 复用其 Push + Issue Sync 逻辑 |
/trellis-parallel | 上游:Multi-Agent Pipeline 创建的 Draft PR 是本命令的输入 |
注意事项
- 验证在 feature 分支上执行 — Phase 2 切换到 feature 分支运行检查,确保验证的是待合并的代码。
- 合并在目标分支上执行 — Phase 3 切换到目标分支执行
git merge --no-ff,保留完整合并历史。
- Spec 更新不阻断 — Phase 4 是「尽力而为」,更新失败不中止交付。但 Phase 2 的 Spec 预检结果会在报告中明确标注。
- 冲突零容忍 — 合并冲突直接中止,不尝试自动解决,保障代码安全。
- 幂等性 — 对同一 PR 重复执行时,已合并/已关闭的 PR 会被跳过。
- 引用精确 — 报告中的 commit hash、文件路径、行号必须是实际值。