mcpField
R
review-bot

review-bot

github.com/kamui開発1333 回インストール1 週間前に更新
リポジトリ

review-bot について

review-botは、公開用Skillから利用するGitHub AppのID確認・トークン取得ツールです。プルリクエストの作者自身がレビューを投稿しない運用に使え、リポジトリ単位のインストールトークンを発行します。リモートからリポジトリを推測せず、秘密鍵はマシンごとに管理します。

主な機能

  1. 01単一リポジトリ用のインストールトークンを発行
  2. 02AppのID、インストール、権限を表示
  3. 03クライアントIDごとにローカル鍵を解決
  4. 04制限付きファイル権限でトークンをキャッシュ
  5. 05セットアップ手順とローカル模擬テストを提供

活用シーン

  1. 01GitHub Appとしてプルリクエストレビューを投稿
  2. 02Appのインストール状況と権限を確認
  3. 03リポジトリごとにレビュー用Appを設定
  4. 04トークンスクリプトとローカル鍵設定を検証

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/kamui/skills --skill review-bot

インストール後、Claude Code で/review-botを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

agents/
openai.yaml
references/
setup.md
scripts/
review_token.py
test_review_token.py

詳細

レビューボット

公開スキルは GitHub App としてレビューを投稿できるため、プルリクエストの作成者が自分の作業をレビューすることはありません。このスキルがその仕組みを担います。App の有効期間が短いインストールトークンを発行するスクリプトを保持し、App の ID を報告します。App 自体はリポジトリごとに宣言され、秘密鍵はマシンごとに保持されます。このスキルは設定ファイルを読み込んだり、リモートからリポジトリを推測したりしません。

Reviewing identity ブロック

リポジトリは docs/agents/issue-tracker.md に、すべての公開スキルが読み取る次のブロックを正確に記述して、レビュー用の App を宣言します。

## Reviewing identity

- **Reviewing app**: <app name>
- **Client id**: <client id>

オプションの 3 つ目のフィールド Review-token command には、トークンを別の場所(たとえば、シークレットストアにあるボットアカウントの PAT)から取得するリポジトリ向けのシェルコマンドをそのまま記述します。このフィールドがある場合、公開側はそのコマンドをそのまま使用し、このスキルを参照しません。

鍵の保存場所

マシンごとに異なる項目は秘密鍵だけです。scripts/review_token.py は、--key、次に REVIEW_BOT_KEY、次に ~/.config/review-bot/<client id>.pem、最後に ~/.config/review-bot/key.pem の順に鍵を解決します。モードは 600 です。クライアント ID を使って鍵を管理することで、1 台のマシンに 2 つのリポジトリの App 用の鍵を保持できます。鍵はリポジトリや同期対象のスキルディレクトリに置かれません。鍵を持つ人は誰でも、その App として投稿できます。

解決

依存側が呼び出す手順です。入力は、トラッカードキュメントのクライアント ID と、プルリクエストのベースリポジトリである <owner>/<repo> です。チェックアウトのリモートは使用しません(フォークをチェックアウトしている場合、そのリモートはフォークです)。

  1. このスキルがインストール済みスキルに含まれていない場合、またはトラッカードキュメントにクライアント ID が記載されていない場合は、以下の該当する unavailable 行を返します。
  2. このスキルのルートから python3 scripts/review_token.py whoami --client-id <id> <owner>/<repo> を実行します。標準出力には ID が出力されます。失敗理由はすべて標準エラーに出力され、終了コードは 1 または 2 です。
  3. 終了コードが 0 の場合は、次の 2 行を返します。
    • reviewer: <slug>。これは app: 行にある括弧内の slug です。GraphQL 形式の、[bot] を除いたログイン名であり、利用側が読み取る値で、finish-it がそのパケットに保存する値です。graphql login: 行から取得してはいけません。この行には接尾辞が付く場合があります。
    • review-token command: <the whoami "review-token command:" line, verbatim>。これは python3 <absolute path to scripts/review_token.py> token --client-id <id> <owner>/<repo> と読み取れます。パスは shlex.quote でシェル用に引用されるため、利用側が sh -c "$tok" に渡して再解析しても安全です。コマンドを sh -c '…' の単一引用符で囲む利用側は、公開時の参照資料に記載されている通常の方法で、含まれる単一引用符を引用します。そのため、スクリプトのパスにスペースやその他のメタ文字が含まれる場合も、この手順を経ることで両方の形式で安全に使えます。絶対パスはインストール済みスキル自身のパスなので、PATH エントリは必要ありません。
  4. 終了コードが 0 以外の場合は、review-bot: unavailable (<reason>) を返します。理由は標準エラーから取得し、次のいずれかの表現にします。
    • インストール済みスキルに含まれていない
    • トラッカードキュメントにクライアント ID がない
    • <path> に鍵が見つからない
    • 鍵を読み取れない
    • 署名に失敗した(App の秘密鍵ではない)
    • <owner>/<repo> に App がインストールされていない
    • フォージが拒否した(HTTP <status>: <message>)
    • ネットワークまたは TLS の失敗

依存側はその後、認証済みユーザーにフォールバックし、理由を記録して、ゲーティングを保留します。解決処理によって実行が停止することはありません。

リポジトリがクライアント ID Iv1.example を宣言し、スキルが ~/.agents/skills/review-bot にインストールされている場合の例:

reviewer: reviewer
review-token command: python3 /home/me/.agents/skills/review-bot/scripts/review_token.py token --client-id Iv1.example acme/widgets

セットアップと確認

ユーザーが /review-bot を呼び出すときに行う手順です。references/setup.md を一緒に確認し、記載されている権限を付与してアプリを作成し、レビュー対象となるすべてのリポジトリにインストールし、キーを生成してダウンロードし、クライアント ID ごとのパスに配置します。次に、ユーザーが指定したリポジトリに対して python3 scripts/review_token.py whoami --client-id <id> <owner>/<repo> を実行し、その出力を表示します。出力には、アプリ、両方のログイン、インストールとその権限、レビュー用トークンのコマンドが含まれます。終了コードが 0 以外の場合は、標準エラー出力と、参照先として示された references/setup.md の手順を報告します(404 は、そのリポジトリを対象としていないインストールを意味します。openssl による拒否は、アプリの秘密鍵ではないファイルを意味します)。

最後に、app: 行とクライアント ID を使って内容を埋め、このリポジトリの docs/agents/issue-tracker.md に貼り付ける正確なブロックを出力します。

## Reviewing identity

- **Reviewing app**: <app name>
- **Client id**: <client id>

スクリプト

scripts/review_token.py にはサブコマンドが 2 つだけあり、それ以外はありません。アドホックな呼び出しをアプリとして実行するには、GH_TOKEN=$(python3 scripts/review_token.py token …) gh … を使います。

  • token --client-id <id> <owner>/<repo> は、そのリポジトリだけを対象とするインストールトークンを標準出力に出力し、それ以外は何も出力しません。トークンは ~/.cache/review-bot/<client id>/<owner>/<repo>.json にキャッシュされます(ルートディレクトリは REVIEW_BOT_CACHE_DIR で上書きできます)。ディレクトリのモードは 700、ファイルのモードは 600 で、.part からのリネームによって書き込まれます。有効期限が 5 分を超えて残っている間は再利用されます。REVIEW_BOT_NO_CACHE=1 を指定すると、常に新しいトークンを発行します。キャッシュを書き込めない場合は標準エラー出力に警告を出しますが、発行したトークンは出力されます。
  • whoami --client-id <id> <owner>/<repo> は、app: <name> (<slug>)、rest login: <slug>[bot]、発行したトークンを使った GraphQL viewer クエリで取得した graphql login: <login>、installation: <id> on <owner>/<repo>、permissions: …、および review-token command: … を出力します。プローブで拒否されたキャッシュ済みトークンは破棄され、標準エラー出力に警告が出た後、1 回だけ再発行されます。

どちらのサブコマンドも --key <path>(または REVIEW_BOT_KEY)と --api <url>(または REVIEW_BOT_API。デフォルトは https://api.github.com)を受け取ります。GitHub Enterprise では https://<host>/api/v3 を指定し、そこから GraphQL エンドポイント <host>/api/graphql が導出されます。キーがグループまたは全ユーザーから読み取り可能な場合、スクリプトは標準エラー出力に警告を出します。

終了コード:0 は成功、1 は Forge から応答があり拒否されたこと(未インストール、HTTP 401/403/404、または発行したトークンがプローブに失敗)、2 は応答がない、またはローカル入力がないこと(キーが見つからない、または読み取れない、openssl が見つからない、またはキーを拒否した、ネットワークまたは TLS の失敗)を示し、標準エラー出力に失敗したコマンドを示します。TLS 検証に失敗した場合は、Install Certificates.command と SSL_CERT_FILE が示されます。呼び出し側は 0 以外かどうかだけを判定し、トークンとして標準出力を取得します。トークンが、スクリプトが実行するコマンドの argv に含まれることはありません。

python3 scripts/test_review_token.py は、使い捨てのキーとローカルの偽 Forge に対してスクリプトを実行します。

コメント