🎼

Claude Codeが書いたissueはClaude Codeに書いてもらう

に公開

タイトルがなんのこっちゃって感じになってしまっていますが、そこの説明はあとにまわすとしまして。

最近以下の記事を読み、個人の開発ワークフローで実践を始めています。内容としては「事前に高品質なissueを作成し、その後Devinに開発依頼をすると成果も上がる」というようなものです。もちろんissueの作成にもDevinを活用しています。

https://zenn.dev/kimkiyong/articles/c707e5f000fab1

人間にとっても楽なのではないか

AIコーディングツールの性能も上がってきていて、一回のコンテキストの中で完結できる場面も増えてきたなと感じるので、こうした手段は回り道になるかもしれませんが、プランから開発までを一気通貫で進めてしまうと私が疲れてしまうので、一呼吸置きながら進めやすいこのやり方は個人的にも好きです。急がば回れ。私の好きな言葉です。

まあそれは置いといて、このフローでの開発の流れとしてはこんな感じでしょうか。

  • AIにGitHub issueを書いてもらう
  • 人間がissueをレビューする
  • issueをもとに開発作業をしてPRを作ってもらう
  • 人間がPRをレビューする

いったんissueに書き出しているので、複数のAIコーディングツールの使い分けも難なくできそうな点も気に入っています。いま私はClaude CodeとDevinを併用しているので、例えば同じissueをそれぞれに実装させて比較することも簡単です。

また、issueやPRのレビューは人間がやっていますが、人間のレビューの前にAIレビューも入れるとさらに楽になりそうに見えます。こうしたところにも、一度issueを作成してもらうメリットもあるなと感じます。

このissue、誰が書いた?

さて、私はというとClaude CodeがメインなのでClaude CodeからissueやPRを作ってもらっているんですが、そうすると、まあなんというか当然ですが、作成者が私になるわけですよ。

他人から見たらなんの変哲もないissueなんですけど、私からすると「書いた覚えのないテキストが自分の名前で出てる!!」みたいなw

個人的なプライベートなリポジトリ内の話なので、なにか問題があるわけじゃないし、あとで見返しても「これAIだな」ってすぐわかるからいいんですけども。せっかくだからBotが作りましたよ〜っていうのがわかるようにしたいなと。

新しくGitHubアカウントを作るという手もありそうですが、今回はGitHub Appsを使ってみることにしました。GitHub Appsを使えばBotとしてissueやPRを作成できるので、今回のような用途にぴったりです。

記事のタイトルにもあるように、Claude Codeが書いたissueは、Claude Code自身として書いてもらえるようになります!

GitHub Appsの登録

まず自分専用のBotを作成します。GitHubの管理画面からNew GitHub Appとして進んでポチポチやるだけで、そんな難しくないです。

https://github.com/settings/apps

Webhookはオフで良くて、Permissionsは以下3点が必要です。

  • Content: Read-only
  • Issues: Read and write
  • Pull requests: Read and write

作成したらPrivate keysを生成してダウンロードしておきます。Client secretsと間違えそうになりますが、Private keysです。

以下の記事に、スクショ付きで丁寧に解説があったので参考にしてください。

https://zenn.dev/coconala/articles/ee36ed7219a2ae

GitHub Appsを作ったら、その後は自分のアカウントにインストールして必要なリポジトリに権限を付けていきます。このときに設定する画面のURLがhttps://github.com/settings/installations/XXXXXXのようになってるはずでして、ここの後ろの数値が後で利用するINSTALLATION_IDなので控えておきます。迷子になってしまったら「GitHubの設定 > Applications > BotのConfigureをクリック」からたどれますので確認してください。

ghのラッパーを用意

BotとしてissueやPRを作成するのに色々手間取ったんですが、最終的にghコマンドの実行時に環境変数を渡すのがもっとも簡単そうでした。以下のように、ghコマンドをラップするシェルスクリプトとしてgh-claudeを用意しました。適当にパスが通る場所に実行権限をつけて置いておきます。スクリプト冒頭にある環境変数の内容は各自の環境にあわせて書き換えてください。

変数名 内容
APP_ID GitHub Appsの設定画面のGeneralで確認できるApp ID
PRIVATE_KEY_PATH GitHub Appsの設定画面からダウンロードできるPrivate keysのパス
INSTALLATION_ID ユーザー個別のID
gh-claude
#! /bin/bash

APP_ID="XXXXXX"
INSTALLATION_ID="XXXXXX"
PRIVATE_KEY_PATH="path to pem file"

function get_jwt() {
   # JWT Header (Base64URL encoded)
   header='{"alg":"RS256","typ":"JWT"}'
   header_b64=$(echo -n "$header" | base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n')

   # JWT Payload (Base64URL encoded)
   now=$(date +%s)
   exp=$((now + 600))  # 10分後に期限切れ
   payload="{\"iat\":$now,\"exp\":$exp,\"iss\":\"$APP_ID\"}"
   payload_b64=$(echo -n "$payload" | base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n')

   # JWT Signature
   signature=$(echo -n "$header_b64.$payload_b64" | openssl dgst -sha256 -sign "$PRIVATE_KEY_PATH" | base64 | tr -d '=' | tr '/+' '_-' | tr -d '\n')

   # Complete JWT
   jwt="$header_b64.$payload_b64.$signature"
   echo "$jwt"
}

function get_token() {
   curl -s -X POST \
     -H "Authorization: Bearer $(get_jwt)" \
     -H "Accept: application/vnd.github.v3+json" \
     https://api.github.com/app/installations/$INSTALLATION_ID/access_tokens \
     | jq -r '.token'
}

GITHUB_TOKEN=$(get_token) gh "$@"

Claude Codeにgh-claudeを使ってもらう

さて、ひと通り準備ができたので、Claude Codeにこのgh-claudeを使ってissue作成をしてもらうようにしましょう。

私は冒頭の記事内で紹介されているissue作成用のメタプロンプトを使わせてもらってカスタムコマンドを作っています。/create-issue あれこれしたいってやると、関連するissueを作ってくれるようになっているんですね。で、今回issueの作成方法としてgh-claudeを使うように指示を追加しました。全体としては、以下のような内容です。

~/.config/claude/commands/create-issue.md
以下の情報を基に熟考してClaude Codeに作業を任せるのに最適なissueを作成しURLを教えてください。
指示が曖昧な場合は、必ず質問をして明確にしてからissueを作成してください。

## issueの作成方法
- `gh-claude issue create` を使ってGitHub issueを作成する(※issue作成の場合のみ`gh-claude`を利用)
- 作業が分割できそうな場合は、適切に分割して複数のissueを作成する

## issueのラベル
- `gh label list` を確認して適切なラベルを付与してください
- ラベルは通常は1つ、多くて2つ、最大で3つまで

## issueのタイトル
- 人間が読みやすいように、簡潔でわかりやすいタイトルを付ける

## issueの内容
- Claude Codeが適切に作業できるように、step-by-stepの指示を含める
- タスクの進捗が保持できるように、タスクリストも含める

### プロジェクト情報
[プロジェクトの技術スタック、アーキテクチャ、重要な設計原則など]

### 実装タスク
[実装すべき機能の詳細]

### 成功基準
[実装が完了したと判断するための明確な基準]

### 関連コード参照
[参考にすべきコードパスや類似実装]

### 制約条件
[考慮すべき非機能要件や制約]

結果

そして、満を持して指示しました!

/create-issue android対応のissue作ってください

すると、いくつかの質疑応答を経て、以下のようなissueが作成されました。

えぇえええ、めっちゃいいんだけど。

なんか完全に自己満足にしかなってない気がしますが。とにかくこれでClaude Codeが作ったissueは、私ではなくClaude Codeが作ったことが明白になりました!めっちゃissue作るぞー!

Discussion