watch-github について
watch-githubは、Claude Codeセッション中にGitHubのプルリクエストとブランチの動きをポーリングするスキルです。レビュー、コメント、CI結果、ヘッド変更、ラベル、競合、マージ、クローズを通知し、指定ワークフローをゲートとして判定できます。
主な機能
- 01プルリクエストとブランチ先端の監視
- 02コメントとレビューの通知
- 03指定ワークフローによるCI判定
- 04ヘッド・ラベル・競合・マージの追跡
- 05状況に応じたポーリング間隔
活用シーン
- 01変更をプッシュした後のCI監視
- 02オープン中のPRのレビューとコメントを追跡
- 03マージ後のメインブランチを監視
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vivswan/ skills --skill watch-githubインストール後、Claude Code で/watch-githubを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSE.mdREADME.md.codex-plugin/plugin.jsonagents/openai.yamlscripts/github-events.mtsscripts/github/check-suites.mtsgh.mtspr-activity.mtsrepository.mtsscripts/targets/branch.mtsci.mtspr.mts詳細
GitHub を監視する
Claude Code のセッションごとにデーモンを 1 つ起動します。セッションがバックグラウンドタスクとして起動し、セッションが監視するプルリクエストとブランチの先端を GitHub でポーリングします。セッションは一度登録すれば、そのまま作業を続けられます。コメント、レビュー、CI の判定、先端の移動、ラベルの変更、ベースとの競合、マージ、クローズが、ポーリングごとに 1 件ずつメッセージとしてセッションに届き、ほかのエージェントも読み取れるログに行として記録されます。
このデーモンは、隣にインストールされた /session-events スキルのもので、このスキルはその GitHub 用ソースです。エンベロープ、ランタイムディレクトリとファイル、ファイルシンク、2 時間の上限については、そちらのページで説明しています。このページでは、ポーリング対象とイベントの内容を説明します。
動作条件:Claude Code のセッション 1 つ、ユーザー 1 人、そのセッションが起動するデーモン 1 つ、認証済みの gh からアクセス可能な GitHub。
実例
プッシュが行われ、PR がオープンになっています。セッションごとにデーモンをバックグラウンドタスクとして一度起動し、続けて 1 行でゲートのワークフローとともに PR を登録します。
bun "<skill-dir>/scripts/github-events.mts" daemon # once per session, as a BACKGROUND task
bun "<skill-dir>/scripts/github-events.mts" watch owner/repo#12 --expect-workflow checks
セッションは作業に戻ります。数分後、ゲートが完了すると、求めなくても会話に次の内容が届きます。
<cross-session-message from="uds:/run/user/1000/session-events/4242.github-events.sock" from-name="github-events" from-mode="bypass">
PR owner/repo#12: CI green on 1a2b3c4d5e6f: 3 workflows
https://github.com/owner/repo/pull/12/checks
automated notice from github-events; no reply needed
</cross-session-message>
「まだ何も変わっていない」という確認にターンを費やす必要はありません。デーモンはセッション自身の子プロセスです。メッセージはエンベロープ内で github-events と名付けられてすぐに届き、セッションが終了するとデーモンも自動的に終了します。
適用する場面
- CI があるブランチで
git pushを実行した直後、または PR をオープンした直後:PR を監視します。 - PR の結果を待っているとき:レビュー、返信、マージ、または「CI は通ったか?」を確認します。
- PR がマージされた直後、またはメインラインに直接プッシュが反映された直後:セッションごとに一度、メインラインのブランチ
owner/repo:mainを監視します。それ以降に届くすべての先端を判定します。
対象
bun "<skill-dir>/scripts/github-events.mts" watch owner/repo#12 --expect-workflow checks --expect-workflow lint
bun "<skill-dir>/scripts/github-events.mts" watch owner/repo:main --expect-workflow checks
| 対象 | イベント | 終了条件 |
|---|---|---|
プルリクエスト owner/repo#n | comment、review、ci、head、label、conflict、merged、closed、trouble | マージまたはクローズ時 |
ブランチの先端 owner/repo:branch | ci、head、trouble | なし。ブランチへのプッシュごとに新しい先端になります |
Issue とセキュリティアラートは、今後このソースでサポートする対象形式です。新しいコマンドやスキルにはなりません。
--expect-workflow <name> は繰り返し指定でき、ゲートを指定します。これは対象をゲートする .github/workflows/ 内のワークフローファイルの name: です。1 回の呼び出しで指定したフラグが、ゲートの完全なセットになります。同じ対象に対する watch を再度実行すると、ゲートとカーソルが置き換えられます。CI は再び判定され、アクティビティの基準点も新たに設定されます。
デーモンが起動していない場合、watch は 3 で終了し、正確な起動コマンドを表示します。PR を初めて検出したとき、それ以前に付いていたコメント、レビュー、ラベルは報告されず、その後に追加されたものだけがイベントになります。CI の判定、マージまたはクローズの状態、およびすでに発生している競合は、その場で判定されます。
イベント
各メッセージには、1 回のポーリングで検出されたイベントが含まれ、それぞれに URL と、末尾の行 automated notice from github-events; no reply needed が付いています。これには絶対に返信しないでください。すべてのテキストが構造化されています。誰が、どこで、いくつ、どの状態で、どの SHA かを示します。コメント、レビュー、ビルドログの内容はメッセージに含まれません。内容を読むには URL を開いてください。
| 種類 | 行の内容 | 対応 |
|---|---|---|
comment | PR owner/repo#12: 2 new comments by octocat at src/x.ts:41, src/y.ts:7 と最新のコメントの URL | URL を開き、レビューラウンドとしてトリアージします |
review | PR owner/repo#12: review by octocat (CHANGES_REQUESTED), 3 comments とレビューの URL | /pr-landing-discipline スキルに従って、同様に対応します |
ci | PR owner/repo#12: CI green on 1a2b3c4d5e6f: 3 workflows とチェックページ。名前付きゲートの範囲外のワークフローが失敗した場合は ; other checks red: claude-review が付きます。または PR owner/repo#12: CI red on 1a2b3c4d5e6f: checks / check / Run tests と失敗した実行の URL | green:続行します。red:抜粋を確認するために gh run view <id> --log-failed を実行し、修正してプッシュします。次の判定は自動的に届きます |
head | PR owner/repo#12: head moved to 1a2b3c4d5e6f; last commit by octocat(プッシュした人ではなく、コミットの作者)。自分のプッシュも含め、ヘッドが動くたびに通知されます | 自分がプッシュしていないヘッドの場合は、ブランチに触れる前にプルします |
label | PR owner/repo#12: label added: merge-when-green。1 回のポーリングで複数ある場合は PR owner/repo#12: labels added: approved, merge-when-green。PR owner/repo#12: label removed: needs-rebase。1 回のポーリングで追加と削除の両方がある場合は、同じ行に ; で区切って記載されます。PR の URL | 自分を指名するラベル、またはゲートを示すラベルには対応します。それ以外は情報として扱います |
conflict | PR owner/repo#12: conflicts with main; rebase needed。リベース後、またはマージテストが再び正常に落ち着いた時点で PR owner/repo#12: conflicts resolved が通知されます。PR の URL | ベースブランチに対してリベースし、プッシュします。プッシュ後も競合が残っている場合は、この行が再び通知されます |
merged | PR owner/repo#12: merged into main | 状況確認を終了します。メインラインの CI はブランチの対象側で対応するものです |
closed | PR owner/repo#12: closed without merging | 状況確認を終了します |
trouble | PR owner/repo#12 is not readable; unwatch it or check access。PR owner/repo#12: CI settled on 1a2b3c4d5e6f with no run of checks; check the workflow name(または no checks on 1a2b3c4d5e6f after 2 polls, so no run of checks)。PR owner/repo#12: 3 reads failed; read the daemon log。または、ポーリングに 3 回失敗した後の /session-events スキルの行 | ツール関連の問題であり、パイプラインの失敗でも成功でもありません。以下の「注意点」を参照してください |
| busy | 種類ではありません。イベントがあるポーリング、保留中のロールアップ、または判定中のヘッドがある場合は、間隔を 60 s に保ちます。何もないポーリングが続くたびに待ち時間は倍になり、120 s、240 s、さらに 300 s になります | 何もしません |
ブランチの対象に関する行は、代わりに branch owner/repo:main: で始まります。コメント行では、セッション自身のログインも含め、すべての投稿者を数えます。同じログインを共有するオーナーとエージェントは区別されず、オーナーによる判断がエコーとして破棄されることもありません。レビューのインラインコメントはレビュー行で数えられ、コメントとして重複して数えられることはありません。
ログインが作成したレビューは、送信されるまでは何も起こりません。送信後は、同じ ID のイベントになります。見落とされる、または通常と異なるケースが 2 つあります。新しいアクティビティによってレビューの読み取り範囲(レビュー 10 件、またはスレッド内の返信 3 件)から外れた後に送信された下書きは検出されません。また、削除によって読み取り範囲内に戻った監視開始前のコメントは、1 回だけ報告されます。
どちらかの側でプッシュが行われると、GitHub はマージテストを再計算し、その間は UNKNOWN を返します。テストが確定するまでは何も通知されません。
CI のルール
- グリーンは、名前を指定したすべてのゲートの最新実行が成功している状態です(スキップも成功として扱います)。ゲートを指定していない場合は、PR の集計ロールアップが
SUCCESSの状態です。ゲートを指定している場合、それ以外で失敗した実行は; other checks red:の後に表示されます。後から傍観者のチェックが赤になった場合、/pr-landing-disciplineスキルではすべてのチェックをグリーンの判定対象とするため、新しいciイベントになります。 - レッドは、名前を指定したゲートの最新実行が失敗またはキャンセルされ、その後に新しい実行がない状態です。ゲートを指定していない場合は、ロールアップが
FAILUREまたはERRORの状態です。レッドの行には、スイートごとに最大 50 件の失敗したジョブを、ワークフロー、ジョブ、最初に失敗したステップの順で表示します。また、実行がないゲートは; no run ofの後に表示されます。 - 実行がないゲートは、ロールアップが保留中の間は保留中です。ロールアップが確定しても実行がない場合、またはチェックがまったくないヘッドに対する 2 回のポーリング後に、1 件の
troubleイベントが発生します。原因は、ゲート名の誤記か、この ref ではトリガーされないワークフローです。 - チェックもゲートもない状態は CI なしを意味し、保留中ではありません。何も通知されず、ロールアップが表示されるまでヘッドは待機します。実行を必ず登録する必要がある場合は、
--expect-workflowでゲート名を指定してください。 - 単位はワークフローです。 再トリガーされた実行は同じ SHA 上に積み重なります。各ワークフローの最新の実行を判定し、古いキャンセル済み実行は新しい実行に置き換えられます。
- 判定後、何かが動いたときにヘッドを再判定します。ゲートを指定したヘッドはポーリングのたびに判定します(ゲートの再実行でロールアップが変化する必要はありません)。ゲートを指定していないヘッドは、ロールアップが変化したときに判定します。同じ判定は通知されず、異なる判定は新しい
ciイベントになります。新しいヘッドは、判定が何もない状態から判定されます。
ポーリング予算
GitHub は GraphQL に独自の制限枠を適用し、Actions の REST エンドポイント(gh run list、gh run watch、gh run view)には別の制限枠を適用します。後者の制限枠は、並行して動くウォッチャーによって、実行時間より長くロックされます。デーモンは GraphQL のみを読み取ります。何かが動いている間は 1 分に 1 回、/session-events スキルの段階的な移行後、何も動いていない間は 5 分に 1 回読み取ります。
1 回のポーリングでは、リポジトリごとに 1 リクエストを使用します。これには、監視中の各 PR の行、監視中の各ブランチの先端、引き続き判定対象となっているか、名前付きゲートを持つ各ヘッドのチェック・スイートが含まれ、これらは 1 つのクエリにエイリアスされます(リポジトリの PR が 30 件増えるごとに 1 リクエスト追加)。これに加えて、以下も必要です。
- 行が変化した PR ごとに 1 回の詳細読み取り(コメント、レビュー、スレッド)。ページをさかのぼって、すでに確認済みの最後のアクティビティまで読み取ります。
- チェック・スイートが 100 件を超えるヘッドごとに 1 回のページ読み取り
- レッド判定ごとに 1 回の読み取り。スイートごとに最大 50 件の失敗したジョブと、そのステップを取得します。
定常状態で何も動いていない場合、5 分ごとにリポジトリあたり 1 リクエストです。メッセージの合間に gh run watch を実行したり、ウォッチャーのサブエージェントを起動したり、PR を手動で読み取ったりしないでください。このセッションでポーリングを行うのはデーモンだけです。
ワークフローの実行が同じ concurrency グループキーを共有している場合、新しいプッシュによって古いヘッドの保留中の実行がキャンセルされるため、判定されるのは最新のヘッドだけです。再びプッシュする前に、その実行を待ってください。
コマンド
usage: github-events.mts <command> [options]
daemon [--interval <s>] [--mode bypass|prompting] [--id <name> [--pid <pid>]]
watch <target> [the source's flags] [--id <name>]
unwatch <target> | --all [--id <name>]
wait [--since <id>] [--timeout <s>] [--id <name>]
poll | status | stop [--id <name>]
the daemon serves the Claude Code session named by CLAUDE_CODE_MESSAGING_SOCKET and exits with it;
--id <name> names a file-sink daemon for a non-Claude agent instead, --pid <pid> ends it with that process;
--mode is the session's permission mode, carried in the envelope: bypass (the default) or prompting;
--interval is 60 s by default, 1 to 86400
targets: <owner/repo>#<n> for a pull request, <owner/repo>:<branch> for a branch tip
--expect-workflow <name> names a workflow whose run must appear on the head before CI reads green; repeatable
the session-events skill must be installed beside this one; without it every command exits 2 naming the install: npx skills add Vivswan/skills -g --skill session-events
files: <dir>/<pid>-<start>.github-events.{state.json,events.jsonl,log} and <dir>/<pid>.github-events.sock for a session; <id>.github-events.* for a file sink;
<dir> is $SESSION_EVENTS_DIR, else $XDG_RUNTIME_DIR/session-events, else $CLAUDE_CODE_TMPDIR/session-events-<uid>, else <os tmpdir>/session-events-<uid>, else /tmp/session-events-<uid>
prints: one message per poll with alerts, wrapped in <cross-session-message from="uds:<socket>" from-name="github-events" from-mode="<mode>"> and ending "automated notice from github-events; no reply needed";
wait prints the new events as JSON lines, then cursor: <id>
exits: 0 ok (stop with no daemon running, and a second daemon start, are ok too); 2 usage, a state file that is not JSON, or no runtime directory;
3 no daemon answers for this session: stderr names the socket and the background command that starts one; 4 wait only: the timeout passed with no newer line
| 終了コード | 意味 |
|---|---|
| 0 | 正常です。デーモンが実行されていない状態での stop も、2 回目の daemon 起動も正常です |
| 2 | 使用方法に関するエラー(CLAUDE_CODE_MESSAGING_SOCKET が設定されておらず、--id も指定されていない、いずれの形式でも対象が指定されていない、ゲート名が空白)、ランタイムディレクトリがない、または /session-events スキルがこのスキルと同じ場所にインストールされていない場合:このスキルと同じ場所にインストールしてください:npx skills add Vivswan/skills -g --skill session-events |
| 3 | このセッションに応答するデーモンがありません。標準エラー出力にソケットと、デーモンを起動する正確なバックグラウンドコマンドが表示されます |
| 4 | wait のみ:新しい行が出ないままタイムアウトしました |
--interval のデフォルトは 60 s です。ファイルシンク(--id)、wait とそのカーソル、ランタイムファイルは /session-events スキルのものです。このソースのログ行は {"id":17,"at":"2026-10-12T14:03:20Z","repo":"owner/repo","pr":12,"sha":"1a2b...","kind":"ci","text":"...","url":"..."} で、ブランチを対象とする行では pr の代わりに branch が使われます。
フリートでは、リードのセッションが自身のバックグラウンドタスクとしてデーモンを実行し、セッションに一致する --mode を指定して、フリートの PR を監視します。ビルダーはそこで watch を実行しません。リードがビルダーにレビュー行への対応を求める場合、その行を 1 件のメッセージで転送します。
注意点
| 表示される内容 | 意味 | 対処方法 |
|---|---|---|
watch がソケットとコマンドを表示して終了コード 3 で終了する | このセッションにデーモンがありません | 表示されたコマンドをバックグラウンドタスクとして実行し、その後もう一度 watch を実行します |
| セッションは実行中なのに、デーモンが 2 時間ほどで自動停止する | バックグラウンドタスクに対するハーネスの上限です。この行の管理元は /session-events スキルのページです | 同じコマンドで再起動します。保存された対象は引き続き監視されます |
3 回のポーリング失敗後に trouble イベントが発生する | gh、ネットワーク、または GitHub が 3 回連続でポーリングを拒否しました。最初に gh auth status を確認してください | デーモンのログに記載された問題を修正します。トークンが古い場合は、デーモンがセッションのトークンを引き継いでいるため、stop してから新しく起動する必要があります |
CI が確定した後、ゲートの実行がないという trouble イベントが発生する | 指定されたワークフローが対象コミットで実行を登録しませんでした | .github/workflows/*.yml と照らし合わせて名前を確認し、正しいセットを指定して watch を再実行します。集計結果を成功と判断してはいけません |
読み取り不可を示す trouble イベントが発生する | PR またはブランチが null を返しています。削除、名前変更、またはアクセス権がない可能性があります | unwatch するか、アクセス権を修正します |
3 回の読み取り失敗を示す trouble イベントが発生する | リポジトリの読み取りには応答があった一方、この対象の詳細またはページ分割されたスイートの読み取りが 3 回連続で失敗しました | デーモンのログを確認します。この対象は毎回のポーリングで再試行され、成功するとカウンターがリセットされます |
| ワークフロー名だけを含む赤い行が表示される | 失敗したジョブの読み取りに失敗しました。判定結果は変わりません | 実行 URL の ID を使って gh run view <id> --log-failed を実行します |
gh が見つからない | daemon のポーリングは最初から失敗します | GitHub CLI をインストールして認証します。それまでは PR の URL とともにプッシュを報告し、監視を黙って省略してはいけません |
Agent ツールで起動されたローカルサブエージェントは、セッションの受信ボックスソケットと PID を共有します。そのため、内部で実行された watch はセッションのデーモンをサブスクライブし、イベントはセッションに届きます。agent teams のチームメイトは独立したプロセスであり、専用のソケットを持ち、自身のデーモンを実行します。