新建 PR
为当前分支在检测到的 PR 平台(Azure DevOps 或 GitHub)上创建一个拉取请求。标题和描述会按照发起用户自己过去的 PR 惯例来起草,而不是使用固定的公司风格,并在创建前展示给用户确认。在获得明确批准之前,永远不会创建 PR——创建 PR 是一个面向外部的操作。
此技能是后端无关的:平台特定的机制(创建 PR、重复检查、打标签、回溯链接)存在于 resources/backends/ 下的后端适配器参考文档中,而与工单链接相关的机制则存在于 resources/trackers/ 下的跟踪器适配器参考文档中。技能主体负责检测平台和跟踪器,加载匹配的适配器,并遵循它们的说明——它自身不包含任何 az/gh 特定的字段解析,也不包含任何跟踪器特定的 ID/URL 解析。它借用了 PR 创建流程的安全护栏,但故意限定范围:它按原样为分支创建 PR——如果分支尚未推送到远程,会先进行推送。它不会合并基础分支,不会删除分支,也不会处理审查评论(这是 resolve-pr-comments 的职责)。
步骤 0 — 检测平台 + 跟踪器,加载适配器,并公告
在开始任何其他操作之前,先确定此次运行的目标后端和跟踪器:
- PR 平台 — 通过
git remote get-url origin检测:dev.azure.com或*.visualstudio.com→ Azure DevOps (resources/backends/azure-devops.md)。github.com→ GitHub (resources/backends/github.md)。- 如果地址不明确或是其他主机,则告知限制并询问用户要针对哪个平台,而不是猜测。
- 问题跟踪器(优先级——第一个匹配的获胜):
- 显式配置优先: 如果
.claude/pr-lifecycle.json(可选,在 .gitignore 中)指定了跟踪器类型,则使用它(并从中获取 Jira 的基础 URL)。 - 否则,根据现有的工单引用推断类型:
[A-Z][A-Z0-9]+-\d+→ Jira(任一平台);纯数字的问题引用 → GitHub Issues——但仅限在 GitHub 远程仓库上(在 Azure DevOps 上,#<n>是工作项链接,不是 GitHub issue,因此裸数字在那里不表示 GitHub Issues)。 - 否则,按平台默认:GitHub 远程仓库 → GitHub Issues(零配置);Azure DevOps 远程仓库 → Jira。
- 根本没有工单 → 不生成跟踪器行(与当前行为相同)。
- Jira →
resources/trackers/jira.md;GitHub Issues →resources/trackers/github-issues.md。
- 显式配置优先: 如果
- 公告 检测到的平台和跟踪器,从而不可能出现静默的错误猜测。
加载匹配的后端和跟踪器适配器,并通过它们运行以下步骤中平台/跟踪器特定的部分。本技能主体中唯一的后端 seam 是识别远程字符串以选择适配器——除此之外不访问任何字段。(适配器路径相对于插件根目录——plugins/pr-lifecycle/resources/backends/ 和 resources/trackers/——而不是技能目录。)
步骤 1 — 检测目标分支
- 读取仓库自身的默认分支;永远不要假设。
git symbolic-ref --short refs/remotes/origin/HEAD会产生origin/<branch>——去掉前缀。该引用由git clone写入,因此通过git init+git fetch构建的远程仓库可能缺少它;此时直接向远程仓库查询git ls-remote --symref origin HEAD,该操作是只读的,不会更改任何本地状态。 - 仅当上述两种方式都解析失败时,才回退到远程仓库实际拥有的
main/master中的任何一个——如果两者都存在,则询问用户。处于重命名过程中的仓库会保留旧分支作为过期分支,因此静默选择可能会导致 PR 基于错误的目标分支,这也会使第 2 步的前置提交数以及第 3 步用于学习调用者惯例的历史记录失效。 - 如果当前分支针对的是发布线(例如
release/2.5),则将其视为回溯(请参阅下面的回溯格式)。 - 如果正确的目标确实不明确,请询问而不是猜测。
步骤 2 — 前置条件(如果任何一项失败,则停止并报告)
在起草任何内容之前运行这些检查,因为每一项都是常见的首次运行障碍:
- 有可提交的更改。 分支必须领先于目标:执行
git fetch,然后git rev-list --count origin/<target>..HEAD必须大于 0。 - 在远程上——如果需要则发布。 创建 PR 需要源分支在远程上。尚未推送的分支不是一个停止条件:在确认后,open-pr 会在第 4 步的创建过程中发布它(
git push -u origin <branch>)。(以非交互方式运行时不推送也不创建——请参阅第 4 步。) - 无重复。 通过后端适配器的重复检查说明检查是否存在此源到目标的现有开放 PR。如果存在一个,停止并引导用户到该 PR——不要创建第二个 PR,也不要在此处修改现有的那个。
步骤 3 — 学习调用者的惯例,然后起草
从 git config user.email(首选)和 user.name 识别调用者,然后读取他们在此仓库中最近的已合并 PR:git log <target> --author="<email or name>"(尝试两种形式;仅当两种都返回空结果时才视为“无历史记录”)。从最近几条中,通过多数原则推断标题大小写和描述布局(分段式与平面项目符号列表)——按提交日期排序最新的那个打破平局,如果只有一条先前的 PR 则直接使用它。公告结果(从您过去的 K 个 PR 中学到 或 没有匹配的历史 -> 使用默认值),从而不可能出现静默的错误猜测。
学习覆盖此仓库和此调用者如何编写内容,而不仅仅是排版:标题大小写、描述布局(分段式与平面项目符号列表)、以及标题的工单前缀形状——括号形式([acme-123] …)、裸形式(acme-123 …)、Conventional Commits 类型(fix(scope): …),或者根本没有前缀。从相同的历史记录中读取形状;如果观察到的 PR 不带工单前缀,则不要添加一个。下面的默认值是在没有历史记录可供学习时使用的内容,绝不是强加给明显做其他事情的仓库的格式。
学习绝不能删除或重新排序以下强制内容——工单链接、摘要和项目符号;第 4 项中的图表是可选的,第 5 项中的来源页脚默认关闭,但是当选择加入来源页脚时,学习必须将其保留在最后并且绝不能丢弃它。如果此仓库是单作者的,不要偏向于学习它——重要的是调用者的惯例,无论该技能在哪个仓库中运行。
默认格式(后备;调用者学习到的惯例会覆盖演示)
标题: 从跟踪器适配器派生工单 ID 及其大小写:
- Jira 跟踪器:
[acme-xxxxx] <简洁的一行摘要>——带括号的小写键(适配器也会为 URL 生成大写形式)。 - GitHub Issues 跟踪器:
#<n> <简洁的一行摘要>——用#<n>引用代替括号形式。 - 未找到工单:省略工单行,并按照此仓库标题化无工单 PR 的方式来命名。
ad-hoc <摘要>是仅当第 3 步的历史记录没有为你提供任何可复制的内容时的后备——它是一个团队的标记,不是要引入到从未使用过它的仓库中的惯例。简单的<摘要>是更安全的默认值。 - 两个或更多不同的工单 ID 表示需要询问选择哪一个,而不是静默地取第一个。
描述(标准 PR):
- 工单链接——由跟踪器适配器构建:对于 Jira,
https://<jira_base_url>/browse/<KEY>(大写键);对于 GitHub Issues,#<n>(GitHub 会自动链接同一仓库的 issue)。这是第一行,以便平台自动链接它;仅当没有工单时才省略整行。 - 摘要——一到两句话。
- 描述——一个项目符号列表,每个单独的更改一个项目符号,格式为操作加简要的原因/影响。省略文件/类/方法/路径标识符——描述意图,不要粘贴差异。
- 一个简短的 ASCII 图表,包裹在围栏代码块中(可选)——仅当图片能让审阅者比文字更快地理解更改时才包含一个;否则就省略。当包含图表时:一个真正的等宽结构图(框/箭头,或一个小的树状/表格——绝不是伪装成图表的散文),保持高层面,包裹在三反引号围栏中,使用纯 ASCII 字符(
+ - | > v)绘制,而不是 Mermaid;将任何宽泛或复杂的图表拆分成更小的图表,而不是强制出一个不可读的块。完整的绘图指导、围栏/编码理由以及一个说明性形状:在resources/diagram-guidance.md中。 - AI 来源标记(选择加入——默认关闭)——页脚(一个
---分隔线,然后是🤖 _Drafted with Claude Code._)以及在第 4 步中应用的ai-assisted标签仅在调用请求明确要求标记/标识/标记 PR 为 AI 辅助时(或传递了显式的选择同意)才添加。没有该措辞时(包括每个自动化的resolve-issue管道调用,它不包含此类措辞)——两者都不添加。在与平台/跟踪器/学习结果相同的行上公告决定(provenance: off (say "mark as AI-assisted" to add),或provenance: on (footer + best-effort label)),从而不可能出现静默丢弃标记的情况。当选择加入时,页脚是每个路径上的最后一个元素——将其附加在学习到的惯例主体之后,并且绝不要让学习丢弃或重新排序它——并且在 Azure DevOps 和 GitHub 上渲染相同,是可移植的标记;标签是随附在它旁边的平台原生徽章(尽力而为——请参阅第 4 步)。如果某个团队将来需要强制性的 AI 披露用于审计,那么届时将其作为配置标志重新引入——现在故意不构建。
回溯(目标是 release/*):
- 标题(Jira 跟踪器):
[acme-xxxxx] [release] <摘要>;(GitHub Issues 跟踪器):#<n> [release] <摘要>。 - 描述是工单链接,然后
cherry pick from <PR-link>,其中后端适配器提供 PR 链接语法(Azure DevOps!<pr_number>,GitHub#<pr_number>——两者都渲染为指向该 PR 的链接),然后——仅当选择加入来源标记时(第 3 步,第 5 项)——AI 来源页脚(---+🤖 _Drafted with Claude Code._)。没有摘要块、项目符号或图表——真正的审查已经发生在原始 PR 上。 - 询问用户(或作为输入接受)cherry-pick 的来源 PR 编号,并重用该 PR 的一行摘要作为
<摘要>。回溯仅学习标题大小写,不学习描述布局。
在每条路径上(包括回溯): 标题和描述都是英文。不要自行添加 git Co-Authored-By 尾部信息——这是一个提交关注点,而不是 PR 描述的关注点,此仓库是否需要它是由仓库自身决定的,可以从其自身历史记录(git log -n 50 --format=%b | grep -c '^Co-Authored-By')中观察到,而不是由本技能决定的。默认为不添加它;如果仓库的提交经常包含它,则遵循该做法而不是覆盖它。AI 来源页脚和 ai-assisted 标签是不同的事情,并且默认关闭——仅在第 3 步(页脚)描述的显式选择加入和第 4 步(标签)应用时才添加——并且绝不是禁止的尾部信息。
步骤 4 — 展示、确认、创建
展示起草的标题和描述,并允许用户编辑它们。然后:
- 独立模式: 仅在用户明确确认后创建。如果源分支尚未在远程上,则首先发布它(
git push -u origin <branch>),然后通过后端适配器的创建说明创建 PR——将完整描述写入临时文件,并将其作为适配器的 body-file 标志传递,绝不要作为内联字符串。适配器记录了平台的文件编码陷阱(例如 Azure DevOps 的az.cmdcp1252/UTF-8@<file>怪癖),以及——仅当选择加入来源标记时(第 3 步)——如何应用ai-assisted标签(Azure DevOps 通过--labels内联创建标签;GitHub 在创建后通过gh pr edit --add-label添加它,因为gh pr create --label在标签不存在时会中止)。当选择加入时,标签无论如何都是尽力而为的(请参见声明的限制);默认情况下不应用任何标签。返回 PR URL。 - 无法获得确认(以非交互方式运行,或在无法提示的子代理内部):**不要推送分支,不要创建 PR。**打印准备好的标题和描述供用户手动创建,并明确说明。不要在非交互上下文中使用在浏览器中打开的标志(例如 Azure DevOps 的
--open)。当选择加入来源标记时,打印的描述已经携带了页脚;告诉用户在创建 PR 时添加ai-assisted标签。默认情况下(未选择加入),不打印或提及任一标记。
不变的原则:在未获得明确的人类确认之前,绝不发布分支或打开 PR——两者都是面向外部的操作。
安全护栏
- 绝不自动解决合并冲突——停止并报告它们。
- 绝不删除分支。
- 未经明确请求,绝不强制推送。
声明的限制
- 如果检测到的平台的 PR 工具缺失或未通过身份验证(请参阅每个后端适配器的前置条件——例如 Azure DevOps 的
az+azure-devops扩展,GitHub 的已认证gh),则说明情况并打印准备好的标题和描述供手动创建——不要静默失败。 - 学习到的惯例是尽力而为的:如果 squash 工作流没有留下描述主体,大小写仍然来自提交主题,布局回退到默认值——会公告,不会静默。
- 来源标记默认关闭——没有页脚,没有标签,除非调用请求显式选择加入(第 3 步,第 5 项)。当选择加入时,
ai-assisted标签是尽力而为的:如果平台拒绝它(一个禁止在 Azure DevOps 上创建即席 PR 标签的组织,或一个在 GitHub 上尚不存在的标签),则放弃该标签,仅凭页脚(已选择加入的标记)创建 PR,并说明情况——后端适配器记录了每个平台的行为。