PRを開く
PRをうまく開くことは、gitの問題である前に調査の問題です。レビュアーは最初の画面で、作者がリポジトリを知っているかどうかを判断します。タイトルの文法、本文の形、コミットの主題 — これらすべてがそれを示します。したがって、作業は次のとおりです。このリポジトリのメンテナーが何を書いているかを学び、それを書くことです。
まず深さを選択
Express は、「とりあえずPRを開く」、「とりあえずマージする」、「これを取り込む」ためのものです。また、調査コストが節約できるレビューコストを上回るほど小さな変更向けです。方向付け、作成、送信、監視の引き継ぎを行います。スタイルスカウトとそのカード、音声調整、散文ゲートはスキップします。Expressが欲しいかどうかを尋ねないでください。言い回しがすでにそれを示しており、確認することはユーザーが避けていた遅延です。
ccx vcs lane --json
ccx vcs diff
ccx vcs ship --no-watch --pr-title-file "$TITLE" --pr-body-file "$BODY"
本文は依然として何が変わったかとなぜかを、リポジトリにテンプレートがあればそれに従って記述し、タイトルは最近マージされた数件のPRの文法に合わせます — gh pr list --state merged --limit 5 --json title を1回読むだけで、スカウトは不要です。Expressは調査を省きますが、本文は省きません。本文のないPRは、どのレーンでも送信しない唯一のものです。
Full はこのファイルの残りの部分であり、自分が所有していないリポジトリ、メンテナーを説得する必要がある変更、またはどこかで初めてPRを開く場合に、そのコストに見合う価値があります。外部リポジトリでは、準拠と丁寧さのパスはExpressでも必須です。これらをスキップするゲストは、自分の時間ではなくメンテナーの往復往路を浪費します。
方向付け
ここではパスが重要です。3つのコマンドがあり、その名前付き出力が下流のすべてで参照されます。
ccx vcs lane --json # レーン、ブランチ、trunk、dirty、github.mine、ダウンスタックPRと本文がないもの
ght repo view --json isPrivate,owner,viewerPermission,pullRequestTemplates,nameWithOwner,defaultBranchRef
ccx vcs guidelines # CONTRIBUTING、PRテンプレート、行動規範、イシュー設定 — カードのパスを出力
次に変更自体のために ccx vcs diff を実行します。
ccx vcs lane はレーンを報告します。選択するのはあなたでもありません。ccx vcs ship は送信時に jj、git、gt のいずれかを選択し、ユーザーが制御していないリポジトリは自動的に gt レーンから外れるため、ship がレーンを報告する前にレーンを仮定するような記述はしないでください。github.mine は所有権の判断です。その背後にあるテストと mine: false より下流のすべては reference/oss.md にあります。ccx vcs guidelines が書き込んだカードを読み、ハード要件と設定項目を分離してください。reference/guidelines.md にその兆候があり、何も公開していないリポジトリ向けの gh api フォールバックもあります。
ハウススタイルを学ぶ
ハウススタイルはディスク上のカードに保存され、リポジトリごとに1回スカウトされキャッシュされます。
bash "${CLAUDE_PLUGIN_ROOT}/scripts/pr-cache.sh" status <owner/name> # fresh | stale:<reason> | missing
bash "${CLAUDE_PLUGIN_ROOT}/scripts/pr-cache.sh" path <owner/name> # キャッシュディレクトリを出力
fresh はスカウト不要です — カードを読んで次に進みます。stale または missing → スカウトを起動します。実行ごとにリポジトリごとに1回だけです。
Agent(subagent_type: "open-pr:pr-style-scout",
prompt: "repo: <owner/name>\ncache: <dir>\nviewer: <gh login>")
スカウトは最近マージされたPRをサンプリングし、ボット、AIが書いたPR、そして外部リポジトリの場合は閲覧者自身のPRをフィルターで除外し、キャッシュディレクトリにカードを書き込みます。パス、短いサマリー、信頼度を返します。そのナレーションではなく、それが書き込んだカードを読んでください。
カードにはサンプルサイズと軸ごとの信頼度が含まれています。サンプルを人間らしく保つフィルターは同時にサンプルを縮小するからです。タイトルの文法と本文構造は慣習です — どのサンプルサイズでも成立します。レビュー応答のトーンと散文レジスタはより少ないシグナルに依存します。confidence: low では、それらはルールではなく傾向であり、PRテンプレートとガイドラインがより重みを持ちます。3つのサンプルから読み取った慣習は、それら3つを記述しています。キャッシュレイアウト、カードスキーマ、陳腐化は reference/style-cache.md にあります。
音声を調整
ユーザーがローカルのWLMプロファイルを持っている場合、フォーマット変更に耐える声の部分を借用します。
wlm profile list
wlm -p <profile> stylecard show # -p はサブコマンドの前にあり、省略不可
WLMカードは長文のブログ散文用に作られています。「絶対に使わないリスト」と単語選択はそのまま転送され、トーンは半分の強度、長さと冒頭部分はまったく転送されません。完全な転送テーブルとプロファイルがない場合のフォールバックは reference/voice.md にあります。リポジトリのカードと音声カードが一致しない場合、リポジトリが優先されます — あなたはそのフォーマットの中でのゲストです。
あなたが制御していないリポジトリ
github.mine: false はレジスタを変更し、書き込み前に2つのパスを追加します(reference/oss.md 参照)。
- 丁寧レジスタ — 変更に関しては直接的、決定に関しては控えめ。数字が主張を支え、メンテナーが彼らの判断を下せるようにします。
- 規格準拠 —
ccx vcs diffをガイドラインカードとチェックリストに照らして確認します。スコープ、スタイル、テスト、ドキュメント、コミット衛生、diffサイズとリポジトリのマージPRの標準との比較。各不一致は修正、または本文内で逸脱を認める一文です。 - イシューファースト — ガイドラインカードがイシューをハード要件としてマークしている場合、開く前に検索します。
gh issue list --repo <slug> --search "<keywords>" --state all。一致なし → イシューのドラフトを作成し、そのドラフトをAskUserQuestionでユーザーに提示します — ドラフトのまま開く / 編集してから開く / 既存のイシューにリンクする / 要件を意図的にスキップする — そしてユーザーの選択に基づいて行動します。イシューを開くことは、誰か他の人のプロジェクト上でユーザーの名前で公開することです。ドラフトは公開しません。
作成
タイトル、本文、コミットの主題は、示された信頼度でスタイルカードに従います。PRテンプレートが存在する場合、それが本文の骨格となります。形容詞で変更を評価する代わりに、数字を使用します。レビュアーは「コールドブートから40ms短縮」を検証し、「はるかに高速」を割り引いて評価します。
<的例> <例 ラベル="売り込み過ぎ"> 「このPRは設定読み込みを大幅に改善します!今でははるかに堅牢です。」 レビュアーが検証できない形容詞で自己評価し、フォーマットが保持しない喜びで表現しています。 </例> <例 ラベル="着地"> 「設定読み込みがキーごとにファイルを再読み込みしなくなりました — 起動時に1回読み込み、コールドブートから40ms短縮。」 変更とその測定効果を述べています。レビュアーは信頼する代わりに検証できます。 </例> </的例>
本文とタイトルをファイルに書き込み、シェル引数には決して使用しないでください。バッククォート、$、コードフェンスを含む本文はコマンドラインをそのまま通過せず、タイトルはそれ以下で拒否されます(Ship 参照)。
BODY=$(mktemp)
TITLE=$(mktemp)
本文は散文なので、送信前に散文ゲートを通過します。slop-cop check "$BODY" --lang=markdown でフラグをすべて受け入れるのではなくトリアージします。
コミットメッセージも同様に処理されます。カードにはこのリポジトリの主題の文法、長さ、マージされたコミットがどのトレーラーを持っているかが記録されています。それらのトレーラーのみに一致させ、他は追加しないでください。歴史に Co-Authored-By: Claude や Generated with Claude Code がないリポジトリでは、ツールを示すトレーラーは、注意深いPRが自動化されているように見える単一の行であり、メンテナーはそれでフィルタリングします。歴史にそれらがあるリポジトリでは、それらを保持することが慣習です。
セッションごとに1つのスタック
1回のセッションからの関連作業は1つのチェーン化されたスタックにまとめ、独立した兄弟ブランチをtrunkから分岐させないでください。たとえdiffが証明可能に重複していなくてもです。「ファイルが重複していない」ことは分割する理由ではありません。兄弟ブランチはチェーンが示すレビュー順序を消去し、ミッドスタックのメカニズムを失います — 1回のリスタックで修正が上のすべてのブランチに伝搬するのに対し、兄弟ブランチはそれぞれ個別にリベースします。依存関係の順序でチェーンし、消費するものが消費するものの上に配置します。まだ進行中のレーンは先端に置き、その下の完了したブランチがその変動の下で再リベースされることがないようにします。メカニズムは reference/stack.md にあります。
PRはフィーチャーサイズの作業単位です。フォローアップ、修正、レビュー応答はオープンPRへのコミットであり、スタックの子ではありません。それらは ccx vcs ship で送信し、--amend を追加してコミットに折り込むか、スタックの先端のみが変更された場合は --tip-only を使用します。親が他の作業の前にマージされる必要がある場合、またはレビューで分割が必要な場合にのみスタック化します。編集ごとではなく、一貫性のあるチェックポイントでプッシュします。各プッシュは実行中のビルドを上書きし、CIとレビューボットを再実行するためです。それでも1時間以内にプッシュしてください。origin がバックアップだからです。
送信
フラグの組み合わせが重要です。
ccx vcs ship --no-watch --pr-title-file "$TITLE" --pr-body-file "$BODY"
タイトルを本文ファイルの隣に1行のファイルとして書き、--pr-title-file を渡します。インラインの --pr-title は使用しないでください。ワークツリー分離されたエージェントのBashサンドボックスは、引用符と git またはシェル名を組み合わせた引数(例:GitHub's ... git)を拒否します。ファイル内のタイトルはコマンドラインに到達しません。Ship はそのタイトルからコミットの主題を、PRの本文からコミット本文を取得するため、-m はタイトルと異なる主題の場合にのみ必要です。
--no-watch は、Ship の組み込みウォッチがCIの終了までブロックするためです。待っているときには正しく、監視がまさに引き継がれようとしているときには間違っています。Ship はすべてのレーンでPRの作成と更新を所有します。それと並行して手動の gh pr create を実行すると、gt レーンが自身のスタックと調整できないPRが生成されます。
すでに開いているPRの場合、Ship は警告し、現在のタイトルと本文を保持するため、修正ではどちらのフラグも指定せず、テキストを変更するPRでは --replace-pr-text を指定します。
gt レーンでは、1回の送信で複数のPRが作成される可能性があり、送信内でまだ本文がないすべてのPRに本文が割り当てられます。--pr-title-file と --pr-body-file はブランチごとに繰り返してスコープを指定できます(--pr-body-file <branch>=<path>; ベア値は先端に適用されます)。ccx vcs lane --json でどのダウンスタックPRに本文がないかがわかります。
拒否は情報であり、再試行ではありません。nothing to commit は以前の送信がすでにこれをマージしたことを意味します。Ship は gt の needs_restack を自身で再生します。それでも Ship がブランチが親から外れているか trunk が移動したために拒否する場合は、ccx vcs stack submit を実行し(または別のレーンがそれを所有している場合は拒否をそのままスタックの所有者に渡し)、その後 Ship を再実行します。
Ship はブランチ、PR番号とURL、head sha を報告します。引き継ぎにはこれら4つすべてが必要です。
監視を引き継ぐ
${CLAUDE_PLUGIN_ROOT} を起動時に呼び出し元で絶対パスに解決し、poll: に実行可能なコマンドを入力します。この変数はこのスキルのテキスト内で置換されます。サブエージェントはそれを受け取りません。poll: の後の文をそのまま渡して、ハーネスがエージェント定義を省略してもウォッチャーがスクリプトを始動できるようにします。
Agent(subagent_type: "open-pr:pr-watcher", run_in_background: true,
name: "pr-watch-<number>",
prompt: "pr: <number>\nurl: <url>\nrepo: <owner/name>\nhead: <sha>\n"
"branch: <branch>\nlane: <gt|jj|git>\ncache: <dir>\nownership: <mine|foreign>\n"
"poll: bash "<abs plugin root>/scripts/pr-poll.sh" <owner/name> <number> <cache>/pr/<number>.json\n"
"Run PR_POLL_WINDOW=40 <poll: command> alone as foreground Bash with timeout: 60000, rerun it at once on DONE window-elapsed, and keep calling until a final verdict: never arm a Monitor or background the call, since neither wakes a subagent, never wrap it in a loop, and never substitute a hand-rolled gh pr checks/bk loop, which cannot see a queue landing. On DONE ready-to-merge, SendMessage main before anything else.")
起動後、ポーリングスクリプトが状態ファイルを書き込んだことを確認します。
bash "${CLAUDE_PLUGIN_ROOT}/scripts/pr-watch-armed.sh" "<cache>/pr/<number>.json"
終了コード1の場合、同じ poll: 行をウォッチャーにもう一度 SendMessage し、チェックを2回目に実行します。それでも失敗した場合は、監視が開始されていないことをユーザーに報告します。エージェントの起動だけではスクリプトが実行されていることは証明されません。
PRごとに1つのウォッチャーです。同じPRに2つ目のウォッチャーがいると最初のものを上書きします。evicted 以外のすべてのレポートは監視を終了します。名前を指定して SendMessage すると次のラウンドのために再開します。evicted: <reason> <detail> メッセージは実行中に到着し、ウォッチャーは呼び出し元がラベルまたはGraphiteのUIで再エンキューするまで監視を続けます。再エンキューする前に修正をプッシュしてください。再エンキューするかどうかは呼び出し元が決定します。
ready-to-merge レポート後: open-pr.on-ready
ready-to-merge レポートは、PRがグリーン、マージ可能、承認済みであることを意味します。すべてのチェックが通過し、head上のすべてのGitHub Actionsチェックスイートが完了し、mergeable が真、キュー状態がクリーンに読み取られ(決して QUEUE unknown ではない)、PRは現在のheadでキューイングも追い出しもされていません。レビュアーの最新レビューが CHANGES_REQUESTED ではなく、REST mergeable_state が blocked(必要な承認が不足している状態)ではありません。ready-to-merge downstack #<n> レポートは、ダウンスタックPR # を待っているスタックPRです(レガシーGraphiteスタックでGraphiteのマージ可否チェックが唯一の未完了チェックである場合を含む)。PR自体は準備ができていますが、そのダウンスタックと一緒にのみマージされます。質問で # を指定し、このPRだけではなくスタック全体をエンキューします。
ユーザーの CLAUDE.md で以下のいずれかの行を読み取ります。
open-pr.on-ready: offer-open(行が設定されていない場合のデフォルト)。同じターンで、AskUserQuestionを通じてPRページを開くかどうかをユーザーに尋ねます。gh pr view <number> --webは「はい」の場合のみ実行します。open-pr.on-ready: offer-merge。同じターンで、AskUserQuestionを通じて「# を今マージしますか?」と尋ねます。「はい」の場合のみリポジトリのキューレベルを追加します。
レポートだけでラベルを追加したり開いたりしないでください。long-running スキルの下では、レポートをランディングデスクに転送します。設定に関わらずランディングデスクが決定を所有します。
すでに ready-to-merge を報告したウォッチャーのPRにキューレベルを追加した後、そのウォッチャーを名前で再開して、グリーンチェックからマージまたは失敗までキューを監視させます。
SendMessage(to: "pr-watch-<number>", message: "Queue label <label> added. Resume the queue watch on the same state file.")
そのレポートはタスク中に通知として到着します。到着するまで作業を続けてください。判定を報告した場合…