GitHub PRコメントをコーディングAIへのプロンプトに変換できるCLIツール「reviewprompt」をClaude Codeで作りました
はじめに
広島在住のdyoshikawaです。
以前、Claude Codeを活用し、各種AIコーディングツールのrulesやMCP、ignoreファイルを一括管理できるrulesyncというツールを開発した旨の記事を公開しました。
今回、やはりClaude Codeを活用して新しくreviewpromptというNode.js製CLIツールを作りましたので紹介します。
また、Claude Codeを使ったCLIツールの開発手法についても触れていきます。
reviewpromptについて
reviewpromptは、GitHub PR上のレビューコメントを抽出することでClaude CodeをはじめとするAIコーディングエージェントへの修正指示プロンプトを生成できるツールです。以下が使い方です。
- ブラウザで対象のGitHub PRを開き、本文に
[ai]
を含めてレビューコメントを追加する。
- 例:
[ai] ここのクエリがN+1になっているので最適化して。
[ai]
を含めるのは通常のレビューコメントと区別するための仕様です。- GitHub PRコメントのSuggestion記法などを使って記述してもOKです。
gh auth login
を済ませたターミナルでnpx reviewprompt --resolve --clipboard https://github.com/owner/repo/pull/123
を実行
- スペースキーでプロンプトにしたいコメントにチェックを入れ、Enterキーで確定します。
--resolve
オプションにより、選択されたコメントは解決済みになります(--delete
オプションに変更することで、選択コメントの削除も可能)。--clipboard
オプションにより、即時にプロンプトがクリップボードにコピーされ、そのままClaude Codeのチャット欄にペーストするだけで使用できます。
レビューコメントのプロンプト化というコンセプトではすでにyoshikoさんのdifitがあります。
reviewpromptはdifitからインスパイアされて開発したものになります。
difitを使うことで「コードの行数指定に紐づけてコメントを付けていく」「複数のコメントを1つのプロンプトにまとめてAIに渡す」ことの体験が良すぎることに気づいたため、自分なりの別解も出してみたいと思い、reviewpromptを開発しました。
違いとしては、difitがツール独自のWeb UI(GitHub PRのUIと見た目や使用感は極めて近い)上でレビューコメントを追加するのに対して、reviewpromptはUI部分をGitHub PRに完全に依存する形にしています。そのため実装にWebフロントエンドは含まれず、CLIのみです。
これには良し悪しがあります。difitがブラウザのLocalStorageにコメント情報を保存しているのに対して、reviewpromptはGitHubのデータストアを状態として利用しています。これにより、例えばファイルごとのViewedチェックボックスの状態がGitHub側で一元管理される点はメリットかなと思っています。コメントもGitHub側に保存されているので、「スマホから投稿したレビューコメントをPCでClaude Codeに渡す」「他のメンバーからのレビューコメントをClaude Codeに渡す」といったこともやりやすいです。
一方で、PR作成前やcommit、pushの前にレビューコメント→プロンプト化のフローを回したいというユースケースはreviewpromptでは対応できません。そのような場合はdifitを使用するべきでしょう。また、difitは自前でUIを持っているがゆえに、git管理さえしていればリモートリポジトリがGitLabでもBitBucketでもBacklogでも使用できるというのは大きな強みです。さらに、difitは急速にコミュニティが拡大しており、コントリビューションも活発なので、reviewprompt側でメリットにしている点が取り込まれる可能性もあるかもしれません。
技術選定
- 言語: Node.js,TypeScript
- CLIライブラリ: Commander,Ink
を選定しました。
Node.js+TypeScriptを採用したのは、単に自分が慣れているし読み書きできる人も多いだろうというのが主な理由です。npmにPublish後は npx {command}
でインストール+実行が簡単にできる点も気に入っています。
コマンド体系の定義や引数・オプションのパースにCommanderを使用しつつ、Inkを組み合わせています。CLIツールではありますがインタラクティブに操作できるチェックボックスが登場するので、React(JSX)でCLIが書けるInkを使うことで宣言的な実装に寄せられるだと考えました。
Claude Code「なんちゃって仕様駆動開発」
Claude Codeを使用し、「なんちゃって仕様書駆動開発」的に開発しました。
まず環境構築を行ってから、仕様書となるマークダウンファイルをリポジトリ内に配置します。今回は SPEC.md
としました(すでに削除していますがこちら)。仕様を書く上でこうすると楽だと思ったやり方は、CLIツールの使用方法のExampleを書いてしまうことです。
実際の例:
reviewprompt は、GitHub の Pull Request のレビューコメントを取得し AI プロンプトを構築する CLI ツールです。
GitHub PR上でレビューコメントをすると、それをAIコーディングツールへの修正指示にそのまま転用することができます。
本文に `@ai` が含まれるレビューコメントを対象に取得し、 `=====` で連結してプロンプトを構築する。
```例:
npx reviewprompt https://github.com/dyoshikawa/reviewprompt/pull/1
# 出力:
# ./src/xxx.ts:L1-L10
# ここをもっとこうして。
# =====
# ./src/yyy.ts:L1-L10
# ここをもっとああして。
```
## npx reviewprompt
`@ai` が含まれるレビューコメントをすべて取得し、連結してプロンプトを構築。デフォルトはコンソール出力で、 `--clipboard` でクリップボードに出力する。
--interactive 対話モードで実行する。`@ai` が含まれるレビューコメントをスペースキーで選択し、Enterキーでプロンプトを構築する
--resolve プロンプトを構築した後に、`@ai` が含まれるレビューコメントを解決済みにする
--delete プロンプトを構築した後に、`@ai` が含まれるレビューコメントを削除する
--mention メンションを `@ai` から変更したい場合。例: `@llm` `@claudecode`
--clipboard クリップボードに出力する
```例
npx reviewprompt https://github.com/dyoshikawa/reviewprompt/pull/1
```
## npx reviewprompt resolve
コメントを解決済みにする。デフォルトは対話モード起動。スペースキーで選択、Enterキーで解決済みにする。
--all 対話モード起動せず、 `@ai` を含む全てのコメントを解決済みにする
--mention メンションを `@ai` から変更したい場合。例: `@llm` `@claudecode`
```例
npx reviewprompt resolve
```
## npx reviewprompt delete
コメントを削除する。デフォルトは対話モード起動。スペースキーで選択、Enterキーで削除する。
--all 対話モード起動せず、 `@ai` を含む全てのコメントを削除する
--mention メンションを `@ai` から変更したい場合。例: `@llm` `@claudecode`
```例
npx reviewprompt delete
```
(現在の仕様とはだいぶ乖離がある点はご留意ください)
文字だけの説明で網羅的な仕様書が書けるのはツール形式としてCLIを選択する強みだと思います。
そこに課題感やツールの目的、仕様を箇条書きのような形で雑に書いていきます。完成したらそれをPlan ModeのClaude Codeに読ませて、実装計画を立てさせました。
仕様駆動開発を支援するツールとしてkiroや弊社のtsumikiを使ってもよかったかもしれませんが、今回のような小さなCLIツールの開発においては、Claude Code+プロンプトの簡易的な手法で賄える感覚です。
実装計画が良さそうであれば、Claude CodeにAcceptEditsモードで開発を依頼します。Claude Codeによる実装と人間(私)による手動テストを繰り返し、なんとなく形になったかなという区切りを得られたら、 SPEC.md
は役目を終えたということで削除し、 README.md
に仕様を、 CONTRIBUTING.md
に開発まわりの情報を移行します(これもClaude Codeにやらせます)。
Claude Code Subagentについて
みなさん、開発にSubagent使われてますでしょうか?
私はSubagentは子プロセス的なものだと思っています。
一般的にLLMは作業が長引くことでロングコンテキストとなりタスク遂行の性能劣化が生じます。この点、全体から見ると枝葉となる各タスクをSubagentに逃がすことで探索過程のコンテキストをSubagent内に閉じ込め、親プロセスが必要とするサマリだけを返すようにします。そうすることで親プロセス側のコンテキスト圧迫が軽減され、連続したタスクでも性能劣化が生じづらくなるという理解をしています。
公式の以下の記述も概ね同じことを指しているのかなと。
コンテキストの保持
各サブエージェントは独自のコンテキストで動作し、メインの会話の汚染を防ぎ、高レベルの目標に集中し続けます。
一方で、現状はSubagentのタスク実行はフリーズするなど不安定に感じることがあります。
近いうちに改善されると思いますし、とても期待している機能なのでアップデートを楽しみにしています。
おわりに
以上、Claude Codeを活用してreviewpromptというCLIツールを開発したというお話でした。
コードに紐づくレビューコメントをAIコーディングエージェントへの修正指示プロンプトに変換するという機能は、AIを使った開発工程において非常に有用に思っています。
参考になれば幸いです。