pr

GitHub PR作成・更新スキル。ユーザーが「/pr」「PR作成」「プルリクエスト作成」と言った時に使用。機能: (1) 既存PR確認と新規/更新モード判定、(2) ブランチ名からIssue番号自動抽出、(3) ベースブランチとの差分分析、(4) Issueリンクプレフィックス設定(ref/close)、(5) PRテンプレート自動生成、(6) PR作成/更新とブラウザ表示。オプション: --c

SKILL.md

GitHub

🔀 PR 作成・更新

[!IMPORTANT] このスキルは GitHub PR を 新規作成 / 更新する単一責務のスキル として動作する。 PR タイトル・本文は CEO が読むため .claude/rules/communication.md の 動作主語 ルール(「〜になった/〜できるようになった」)に従う。 PR には intent ラベルを付与しない(Issue #575: intent の SoT は Issue ラベル)。 Issue リンクは Closes #N / Refs #N(#N 形式必須、URL 形式は close-on-feature-merge.yml の抽出対象外)。 結果のみを簡潔に返す。途中経過は出力しない。

GitHub PR を作成・更新する。

🌳 worktree モード

--worktree <path> が指定された場合、全操作を指定パス内で実行する。

  • Bash: 全コマンドを cd <path> && command で実行する。
  • Read/Write/Edit: <path>/ を基準とした絶対パスを使用する。
  • サブスキル呼び出し: --worktree <path> を引き継ぐ。
  • 未指定時は従来通り CWD で実行する(後方互換)。

🔄 ワークフロー

1. リポジトリ情報の取得

gh repo view --json owner,name,defaultBranchRef --jq '.owner.login + "/" + .name + " " + .defaultBranchRef.name'

REPO_OWNER/REPO_NAME と DEFAULT_BRANCH として保持する。

2. 既存 PR の確認とベースブランチの特定

以下の優先順で検出する。

1. 既存 PR から取得(最優先):

gh pr view --json baseRefName,number --jq '.baseRefName + " " + (.number | tostring)'

取得できれば更新モード。baseRefName をベースブランチとする。

2. merge-base で推定(新規 PR 時):

候補ブランチ(DEFAULT_BRANCH, 直近の feature ブランチ等)との merge-base を比較し、最も HEAD に近いものを選ぶ。

git merge-base HEAD origin/$DEFAULT_BRANCH

3. デフォルト: DEFAULT_BRANCH(ステップ 1 で取得済み)

3. Issue 番号の抽出

ブランチ名から取得する(例: dev/12345_feature → Issue #12345)。

4. ベースブランチとの差分確認

git diff origin/$BASE_BRANCH...HEAD
git log --oneline origin/$BASE_BRANCH...HEAD

5. Issue リンクのプレフィックス決定

  • --close オプション指定時: Closes(GitHub auto-close キーワード、PR マージで Issue が自動 close)。
  • --ref オプション指定時: Refs(auto-close 対象外、参照のみ。親エピックなど)。
  • 未指定時: ユーザーに質問する(デフォルト: Closes)。

プレフィックスは Closes / Refs の大文字始まりで統一する。.github/workflows/close-on-feature-merge.yml が (close[sd]?|fix(es|ed)?|resolve[sd]?)[[:space:]]+#[0-9]+ を抽出対象とするため、書式は Closes #N (URL 形式ではなく #N 形式)でなければ feature ブランチへのマージ時に Issue が auto-close されない。詳細は .claude/rules/workflow.md「PR 本文の Issue リンク(auto-close キーワード)」を参照。

6. PR テンプレート作成

.github/PULL_REQUEST_TEMPLATE.md が存在すればそれを読み込み、差分分析に基づいて各セクションを埋める。テンプレートが存在しなければ、以下の構成で本文を生成する。

  • 概要(背景・課題 → Before/After → 懸念事項)
  • Issue リンク

概要の書き方:

[!IMPORTANT] 可読性が最優先。 マークダウンと絵文字を最大限活用し、レビュワーが diff を開く前にスキャンだけで「誰のために・何が・どう変わるか」を把握できる状態に仕上げる。 装飾は控えめにせず、意味を見やすく示すために積極的に使う。

このセクションは「この PR が当事者にとって何をもたらすか」をレビュワーに伝える場。diff を開く前に変更の全体像・妥当性・スコープが把握できることをゴールとする。

固定テンプレートで埋めるよりも、後述の「指針」を満たすことを優先する。差分の性質(新機能追加・バグ修正・リファクタ・依存更新・パフォーマンス改善・ドキュメント改修・テスト追加 等)に応じて、見出し構成・装飾・粒度は LLM の判断で柔軟に組み立てる。

PR タイトル・本文は CEO が読むため .claude/rules/communication.md の 動作主語 ルール(「〜になった/〜できるようになった」)を必ず守る。下記「指針」「禁止パターン」はその上に重ねる運用追加分。

変化の主役を見極める

概要欄の語り口は「この PR で何が・誰のために変わるか」で大きく変わる。本文作成に入る前に、変化の主役を 1〜2 行で言語化しておく。これ以降の「指針」「使える見出し要素」「禁止パターン」は、ここで定めた主役を軸に運用する。

主役は典型的には次のいずれかになるが、列挙したものに縛られなくてよい。

  • 人(エンドユーザー・運用担当者・他チームの開発者・レビュワー・プロダクトオーナー・サポート担当 等の体験や操作)
  • 外向きの挙動(API レスポンス・CLI 出力・画面表示・通知・ログ・公開ライブラリの I/F・エラーメッセージ 等)
  • コードの内部品質軸(責務分離・依存方向・テスタビリティ・複雑度・拡張点)
  • 再現していた事象(バグ修正の場合)
  • その他(ドキュメント読者・運用フロー・デプロイ体験・セキュリティ姿勢 等、PR の性質に応じて自由に設定)

たとえば以下のように、PR ごとに主役を当てはめる。

  • 認証ミドルウェア追加 → 外向きの挙動(未認証リクエストがどう扱われるようになるか)か コードの内部品質軸(既存ミドルウェア群との責務分離)のどちらが支配的か。
  • DB クエリの N+1 解消 → 外向きの挙動(レスポンス時間がどう変わるか)か コードの内部品質軸(クエリ発行箇所の集約方針)のどちらが支配的か。

複数の主役が並ぶ場合は 最も支配的なものを 1 つ 選び、残りは副次的な見出しに格納する。

指針(MUST)

  1. マークダウン・絵文字を最大限活用する

    要素 用途
    見出し絵文字(1 つ) 意味のグルーピング標識(## トップレベルから積極的に付ける)
    テーブル / 🔴-🟢・❌-✅・🟥-🟩 対比リスト 比較・前後対照
    > [!NOTE] / > [!IMPORTANT] / > [!WARNING] コールアウト 重要な前提・補足・注意
    太字 強調
    箇条書き 列挙
    番号付きリスト 手順
  2. 短く・スキャンしやすく書く

    • 1 文は短く保つ(おおむね 50 字以内が目安)。
    • 1 項目 1 論点を保つ。
    • 論点が増えるならサブリストで段落化する。
    • 太字の体言止め見出し → 改行 → 簡潔な説明 の構造を優先する。
  3. 変化の主役を主語にする

    • 上記「変化の主役を見極める」で言語化した主役を、概要欄の中心的な主語に据える。
    • 主役が 人や外向きの挙動 なら、クラス名・メソッド名・ファイルパスなどの実装語彙は原則使わない。
    • 主役が コードの内部品質軸 なら、形容詞での曖昧表現を避け「何が・どこから・どこへ・どう動いたか」を構造として示す。
    • 主役が 再現していた事象 なら、「どんな条件で何が起きていたか」「修正後は何が起きなくなるか」を書く。
    • 「○○メソッドを追加した」だけ/「より見通しが良くなった」だけで終わらせない。
  4. PR の位置づけを明示する

    • 前段 PR・後続 PR・関連 Issue があれば、本 PR が全体のどこに当たるかを示す。
    • スコープ外(このPRでやらないこと・別 Issue に切り出した内容)を明示し、レビュワーの期待値をそろえる。
  5. 設計判断は理由とセットで残す

    • 「なぜこの場所・この設計・この仕様にしたか」を書く。
    • レビュワーの「なぜ別案ではないのか?」を先回りで潰す。
    • 別案を検討して却下した場合は、その理由も短く添える。

使える見出し要素(差分に応じて取捨選択)

該当する内容がないものは見出しごと省略する。「特になし」「変更なし」と書かない。

絵文字 見出し例 使うとき
🎯 背景・目的 なぜやるか、運用上の課題、保守上の痛み
🔄 Before / After 当事者の挙動・体験の対比
🧭 設計判断 なぜこの選択か、別案を採らなかった理由
🛣️ 仕様・エンドポイント 入出力・境界条件・エラーレスポンス
🆕 追加する機能 新しくできるようになる操作・表示
♻️ リファクタの動機 変更前のコードの何が辛かったか
🧱 構造の変化 責務・依存方向・拡張点が どこから・どこへ・どう 動いたか
🔍 動作不変性の担保 既存テスト・追加テスト・カバレッジで等価性をどう保証したか
🧪 テスト観点 何を担保したか(境界値・異常系・回帰 等)
🚧 スコープ外 このPRでやらないこと、後続 Issue でやること
🖼️ 位置づけ 前段/本 PR/後続のマップ

どの見出しを使うかは、上記「変化の主役を見極める」で言語化した主役を示せるかで判断する。種別と見出しを機械的に対応させない。

禁止パターン

  • ❌ 変化の主役と無関係な実装詳細の羅列 で終わる
    • 人や外向きの挙動が主役なのに「メソッド追加・型分割・カラム追加」だけを並べる。
    • コードの内部品質軸が主役なのに、挙動が変わったかのように書く。
  • ❌ 形容詞だけで具体性のない記述(「より使いやすく」「より柔軟に」「より見通しが良く」「保守性が向上」だけで止まる)。
  • ❌ 1 項目に複数論点を詰めて長文化 する(:・〜のため・〜ように で結論・背景・理由を 1 文に連結 / 折り返しが何行も発生する 1 文)。
  • ❌ diff を読めば分かることをそのまま書き写す。
  • ❌ 装飾目的だけの絵文字・テーブル(1 つの見出しに絵文字を複数並べる/中身が薄いのにテーブル化する)。

Issue リンクの書き方:

PR 本文には auto-close キーワードを #N 形式で記載する(URL 形式は使わない)。

{prefix} #{ISSUE_NUMBER}

例:

Closes #123        # ← 子 Issue / 通常 Issue を auto-close する
Refs #345          # ← 親エピック Issue を参照するだけ(auto-close 対象外)

複数 Issue を close する PR では複数行記載する:

Closes #123
Closes #124

既存の 📍 関連 セクション(人間向けナビゲーション)を残す場合も、上記の Closes #N / Refs #N 行を必ず併記する。

7. PR 作成 / 更新

新規作成:

PR には intent ラベルを付与しない(Issue #575 確定: intent の SoT は Issue ラベル、PR は CC prefix が機械可読保険となる)。レビュー判定(intent × severity)は /vibecorp:pr-fix / /vibecorp:review-loop が PR 本文から Issue 番号を解決して gh issue view --json labels で intent を直接取得する設計に切り替わった。

# PR 作成(intent ラベル付与なし)
git push origin HEAD && gh pr create --title "$ISSUE_TITLE" --body "$PR_BODY" --base "$BASE_BRANCH"

intent ラベルは Issue 側で SoT 管理される。Issue 側の intent-label-issue-check.yml ジョブが 1 Issue 1 intent を機械強制する。

auto-merge の有効化(新規作成時のみ):

gh pr merge --squash --auto

リポジトリ設定で auto-merge が無効の場合はスキップし、結果報告にその旨を記載する。

更新:

git push origin HEAD && gh pr edit $PR_NUMBER --title "$ISSUE_TITLE" --body "$PR_BODY"

作成 / 更新後にブラウザで表示:

gh pr view --web

8. /vibecorp:session-harvest の末尾同期呼出(preset standard 以上、新規 PR 時のみ)

PR 作成 + auto-merge 設定が完了した後、セッションで生まれた知見を knowledge/buffer に蓄積するため /vibecorp:session-harvest を末尾同期で呼ぶ。PR 作成フローはブロックしない(呼出順: PR 作成 → auto-merge 設定 → session-harvest)。

新規 PR 時のみ実行: ステップ 2 で PR_NUMBER が取得できた場合は既存 PR 更新であり session-harvest は呼ばない(同一セッションの知見が重複蓄積するのを防ぐ)。PR_NUMBER が空の場合のみ新規作成と判定する。

# 新規 PR の場合のみ実行(既存 PR 更新時はスキップ)
if [ -z "${PR_NUMBER:-}" ]; then
  PRESET="$(awk '/^preset:/ { sub(/^preset:[[:space:]]*/, ""); print; exit }' \
    "${CLAUDE_PROJECT_DIR:-.}/.claude/vibecorp.yml")"
  case "$PRESET" in
    standard|full)
      # /vibecorp:session-harvest は minimal プリセットでは配置されないため standard 以上のみ
      if ! /vibecorp:session-harvest; then
        echo "[pr] /vibecorp:session-harvest が失敗しました(PR 作成は成功)" >&2
      fi
      ;;
  esac
fi

失敗しても PR 作成結果は成功扱い。呼出は末尾同期のため PR URL の返却前に完了する。

⚠️ 制約

  • PR タイトル: gh issue view {番号} --json title で取得した Issue タイトルを使用する。
  • プッシュと PR 作成の連結: && で連結実行する。
  • チェックボックス: 自動でチェックしない。
  • draft モード不使用: レビュー可能な状態で作成する。
  • 一時ファイル禁止: 標準入力から body 設定する。
  • --force は使用しない。
  • 明示的な要求なしに既存 PR を閉じない。
  • jq では string interpolation \(...) を使わない — Bash 上で \ がエスケープ文字、() がサブシェルとして解釈され、意図しない展開やパースエラーを引き起こすため。必ず + で結合する。
  • コマンドをそのまま実行する — 2>/dev/null、|| echo、; echo 等のリダイレクトやフォールバックを付加しない(根拠)。

📤 返却フォーマット

{新規/更新} {PR URL}

🔗 関連ルール

  • ワークフロー規約(PR 本文の Issue リンク): .claude/rules/workflow.md
  • CEO 報告向け文面規約: .claude/rules/communication.md
  • intent ラベル定義: .claude/rules/intent-labels.md
  • レビュー観点(intent 別): .claude/rules/review-observations.md
  • 関連スキル: /vibecorp:ship / /vibecorp:pr-fix / /vibecorp:pr-fix-loop
  • プロンプト作成基準: .claude/rules/prompt-writing.md
  • マークダウン規約: .claude/rules/markdown.md
  • シェル規約: .claude/rules/shell.md