PRを開く
検出されたPRプラットフォーム(Azure DevOps または GitHub)上で、現在のブランチのプルリクエストを開きます。タイトルと説明は、固定のハウススタイルではなく、呼び出し元ユーザーの過去のPR規約に合わせて下書きされ、確認のために表示されます。PRは明示的な承認なしには作成されません — PRを開くことは外部に影響を与えるアクションです。
このスキルはバックエンドに依存しません。プラットフォーム固有のメカニズム(PR作成、重複チェック、ラベル、バックポートリンク)は resources/backends/ 以下のバックエンドアダプタリファレンスドキュメントに、チケットリンクのメカニズムは resources/trackers/ 以下のトラッカーアダプタリファレンスドキュメントに記述されています。スキル本体はプラットフォームとトラッカーを検出し、対応するアダプタをロードしてそのレシピに従います — 独自の az/gh 固有のフィールド解析やトラッカー固有のID/URL解析は一切保持しません。PR作成フローの安全レールを借用していますが、意図的に範囲を絞っています。ブランチをそのまま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イシューではないため、単なる数字はそこではGitHub Issuesを意味しません)。 - そうでなければプラットフォームでデフォルト: GitHubリモート → GitHub Issues(ゼロコンフィグ); Azure DevOpsリモート → Jira。
- チケットが全くない → トラッカー行は生成しません(現在と同じ動作)。
- Jira →
resources/trackers/jira.md; GitHub Issues →resources/trackers/github-issues.md。
- 明示的な設定が優先:
- 検出されたプラットフォームとトラッカーをアナウンスし、誤った推測が黙って行われることを防ぎます。
対応するバックエンドアダプタとトラッカーアダプタをロードし、以下のステップのプラットフォーム/トラッカー固有の部分をそれらを通して実行します。このボディにおける唯一のバックエンドの継ぎ目は、アダプタを選択するためのリモート文字列の認識です — それ以上のフィールドアクセスはありません。(アダプタのパスはプラグインルートからの相対パスです — plugins/pr-lifecycle/resources/backends/ および resources/trackers/ — スキルディレクトリからの相対パスではありません。)
ステップ 1 — ターゲットブランチの検出
- リポジトリ自身のデフォルトブランチを読み取ります。決して推測しません。
git symbolic-ref --short refs/remotes/origin/HEADはorigin/<ブランチ>を返します — プレフィックスを除去します。この参照はgit cloneによって書き込まれるため、git init+git fetchで構築されたリモートにはない可能性があります。その場合はgit ls-remote --symref origin HEADでリモートに直接問い合わせます。これは読み取り専用でローカル状態を変更しません。 - 両方とも解決できない場合のみ、リモートが実際に持っている
main/masterのいずれかにフォールバックします — そして両方存在する場合は尋ねます。名前変更の途中にあるリポジトリは古い方を stale ブランチとして保持するため、黙って選択すると誤ったターゲットにPRがベースされ、ステップ2の先行カウントとステップ3が呼び出し元の規約を学習する履歴も無効になります。 - 現在のブランチがリリースライン(例:
release/2.5)をターゲットとしている場合は、バックポートとして扱います(以下のバックポート形式を参照)。 - 正しいターゲットが真に曖昧な場合は、推測するのではなく尋ねます。
ステップ 2 — 前提条件(いずれかが失敗した場合は停止して報告)
下書きの前にこれらを実行します。それぞれが一般的な初回実行時のブロッカーであるためです。
- PR にコミットがあること。 ブランチはターゲットより先行している必要があります:
git fetchを実行し、git rev-list --count origin/<ターゲット>..HEADが 0 より大きいことを確認します。 - リモート上にあること — 必要に応じて公開。 PR を作成するにはソースブランチがリモート上にある必要があります。まだプッシュされていないブランチは停止ではありません: 確認後、open-pr はそれを公開します(
git push -u origin <ブランチ>)。PR作成の一部としてステップ4で行います。(非対話的に実行する場合はプッシュも作成も行いません — ステップ4を参照。) - 重複がないこと。 バックエンドアダプタの重複チェックレシピを使用して、このソースからターゲットへの既存のオープンPRがないか確認します。存在する場合は停止し、ユーザーにそれを知らせます — 2つ目のPRを開かず、既存のものをここで変更もしません。
ステップ 3 — 呼び出し元の規約を学習し、下書き
git config user.email(推奨)と user.name から呼び出し元を特定し、このリポジトリでその人の最近マージされたPRを読み取ります: git log <ターゲット> --author="<メールまたは名前>"(両方の形式を試し、両方が何も返さない場合のみ「履歴なし」として扱います)。最後のいくつかから、タイトルの大文字小文字と説明のレイアウト(セクション形式かフラットな箇条書きか)を多数決で推測します — 最新のコミット日が同点を破り、単一の先行PRが直接使用されます。結果をアナウンスします(あなたの過去K件のPRから学習しました または 一致する履歴なし -> デフォルトを使用)。黙って誤った推測が行われることを防ぎます。
学習はこのリポジトリとこの呼び出し元がどのように記述するかをカバーします。単なるタイポグラフィだけでなく、タイトルの大文字小文字、説明のレイアウト(セクション形式 vs フラットな箇条書き)、そしてタイトルのチケットプレフィックスの形状 — 括弧付き([acme-123] …)、ベア(acme-123 …)、Conventional Commits タイプ(fix(scope): …)、またはプレフィックスなし。同じ履歴から形状を読み取ります。観測されたPRにチケットプレフィックスがない場合は、追加しません。以下のデフォルトは、学習する履歴がない場合に使用するものであり、明らかに異なることを行っているリポジトリに押し付ける形式ではありません。
学習は以下の必須コンテンツ — チケットリンク、サマリー、箇条書き — を決して削除したり並び替えたりしてはいけません。アイテム4の図はオプションであり、アイテム5の出典フッターはデフォルトでオフですが、出典フッターがオプトインされた場合、学習はそれを最後に保ち、決して削除してはいけません。このリポジトリが単一著者であっても学習をバイアスしないでください — 重要なのは呼び出し元の規約であり、スキルが実行されるリポジトリに関係ありません。
デフォルト形式(フォールバック。呼び出し元の学習された規約が表示を上書き)
タイトル: チケットIDとその大文字小文字をトラッカーアダプタから導出:
- Jiraトラッカー:
[acme-xxxxx] <簡潔な1行サマリー>— 括弧で囲まれた小文字キー(アダプタはURL用の大文字形式も提供します)。 - GitHub Issuesトラッカー:
#<n> <簡潔な1行サマリー>— 括弧形式の代わりに#<n>参照。 - チケットなし: チケット行を省略し、このリポジトリがチケットなしのPRに使用するタイトルにします。
ad-hoc <サマリー>はステップ3の履歴が何もコピーするものを与えなかった場合のみのフォールバックです — これは1つのチームのマーカーであり、これまで使用したことのないリポジトリに導入する規約ではありません。プレーンな<サマリー>がより安全なデフォルトです。 - 異なるチケットIDが2つ以上ある場合は、黙って最初のものを取るのではなく、どれかを尋ねます。
説明(標準PR):
- チケットリンク — トラッカーアダプタによって構築: Jiraの場合は
https://<jira_base_url>/browse/<KEY>(大文字キー); GitHub Issuesの場合は#<n>(GitHubは同じリポジトリのイシューを自動リンク)。プラットフォームが自動リンクできるように最初の行にします。チケットがない場合のみ行全体を省略します。 - サマリー — 1~2文。
- 説明 — 箇条書き。個別の変更ごとに1箇条書きを アクションと簡単な理由/影響 として。ファイル/クラス/メソッド/パスの識別子は省略 — 意図を説明し、差分を貼り付けないでください。
- 短いASCII図。フェンスで囲まれたコードブロックでラップ(オプション) — 図があればレビュアーが散文よりも早く変更を理解できる場合のみ含めます。そうでなければ省略します。含める場合: 実際のモノスペース構造図(ボックス/矢印、または小さなツリー/テーブル — 散文を図に仕立てたものではありません)、高レベルに保ち、トリプルバックティックのフェンスで囲み、プレーンなASCIIグリフ(
+ - | > v)で描画し、Mermaidは使用しません。幅が広いまたは複雑な図は、1つの読みにくいブロックに押し込むのではなく、小さな図に分割します。完全な描画ガイダンス、フェンス/エンコーディングの根拠、および例示的な形状:resources/diagram-guidance.md。 - AI出典マーカー(オプトイン — デフォルトでオフ) — フッター(
---区切り、その後🤖 _Drafted with Claude Code._)とステップ4で適用されるai-assistedラベルは、呼び出し元のリクエストが明示的にPRをAI支援としてマーク/ラベル/フラグ付けするよう要求した場合のみ(または明示的なオプトインが渡された場合)追加されます。そのような文言がない場合 —resolve-issueパイプライン呼び出しを含むすべての自動化はそのような文言を運びません — どちらも追加しません。プラットフォーム/トラッカー/学習結果と同じ行で決定をアナウンスします(provenance: off("AI支援としてマーク"と言うと追加)、またはprovenance: on(フッター + ベストエフォートラベル))。黙ってマーカーが削除されるのを防ぎます。オプトインされた場合、フッターはすべてのパスで最後の要素です — 学習された規約の本文の後に追加し、学習がそれを削除または並び替えしないようにします — そしてAzure DevOpsとGitHubで同じようにレンダリングされます。これはポータブルマーカーです。ラベルはそれに加えてプラットフォームネイティブのバッジです(ベストエフォート — ステップ4を参照)。チームが監査のために必須のAI開示を必要とする場合は、その時点で設定フラグとして再導入します — 意図的に今は構築しません。
バックポート(ターゲットが release/*):
- タイトル(Jiraトラッカー):
[acme-xxxxx] [release] <サマリー>; (GitHub Issuesトラッカー):#<n> [release] <サマリー>。 - 説明はチケットリンク、次に
cherry pick from <PRリンク>。ここでバックエンドアダプタがPRリンクの構文を提供します(Azure DevOps!<pr_number>、GitHub#<pr_number>— どちらもそのPRへのリンクとしてレンダリングされます)。次に — 出典がオプトインされている場合のみ(ステップ3、項目5) — AI出典フッター(---+🤖 _Drafted with Claude Code._)を追加します。サマリーブロック、箇条書き、図はありません — 実際のレビューは元のPRで行われました。 - チェリーピック元のソースPR番号をユーザーに尋ねるか(または入力として受け入れ)、そのPRの1行サマリーを
<サマリー>に再利用します。バックポートはタイトルの大文字小文字のみを学習し、説明のレイアウトは学習しません。
すべてのパスで(バックポートを含む): タイトルと説明は英語です。独自の Co-Authored-By トレーラーをgitに追加しないでください — それはコミットの関心事であり、PR説明のものではありません。このリポジトリがそれを望むかどうかは、リポジトリ自身の履歴(git log -n 50 --format=%b | grep -c '^Co-Authored-By')から観察可能であり、このスキルが決定するものではありません。デフォルトでは追加しないでください。リポジトリのコミットが定期的にそれを運んでいる場合は、それを上書きするのではなく従います。AI出典フッターと ai-assisted ラベルは別物であり、デフォルトでオフです — ステップ3(フッター)で説明され、ステップ4(ラベル)で適用される明示的なオプトインがある場合のみ追加されます — そして決して禁止されたトレーラーではありません。
ステップ 4 — 提示、確認、作成
下書きしたタイトルと説明を表示し、ユーザーが編集できるようにします。その後:
- スタンドアロン: ユーザーが明示的に確認した後にのみ作成します。ソースブランチがまだリモートにない場合は、先に公開します(
git push -u origin <ブランチ>)。その後、バックエンドアダプタの作成レシピを使用してPRを作成します — 完全な説明を一時ファイルに書き込み、インライン文字列としてではなくアダプタのボディファイルフラグとして渡します。アダプタはプラットフォームのファイルエンコーディングの落とし穴(例: 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)、その旨を伝え、準備されたタイトルと説明を手動作成用に印刷します — 黙って失敗しないでください。 - 学習された規約はベストエフォートです。スカッシュワークフローが説明本文を残さなかった場合、大文字小文字はコミット件名から得られ、レイアウトはデフォルトにフォールバックします — アナウンスされ、黙ってはいません。
- 出典マーカーはデフォルトでオフです — 呼び出し元リクエストが明示的にオプトインしない限り、フッターもラベルもありません(ステップ3、項目5)。オプトインされた場合、
ai-assistedラベルはベストエフォートです。プラットフォームが拒否した場合(Azure DevOpsでアドホックなPRタグを許可しない組織、またはGitHubでまだ存在しないラベル)、ラベルをドロップし、フッターのみでPRを作成し(オプトインされたマーカー)、その旨を伝えます — バックエンドアダプタはプラットフォームごとの動作を文書化します。