Initial commit

This commit is contained in:
Zhongwei Li
2025-11-29 18:23:35 +08:00
commit 0fe2638c61
150 changed files with 37511 additions and 0 deletions

57
commands/branch-create.md Normal file
View File

@@ -0,0 +1,57 @@
# ブランチ作成コマンド
新しいフィーチャーブランチを作成します。
## 使用方法
```bash
/branch-create [ブランチ名]
```
## ブランチ命名規則
- [Conventional Branch](https://conventional-branch.github.io/) に従う
- 形式: `feature/[FeatureName]-[実装した機能名]`
- 例: `feature/admin-user-role-edit-invite-form`
## 処理手順
1. 現在の変更をstashして保存
2. メインブランチから新しいブランチを作成
3. stashした変更を適用
4. ブランチの作成完了を確認
## 実装
```bash
# 現在の変更をstashに保存
echo "💾 現在の変更をstashに保存中..."
git stash push -m "branch-create: temporary stash before creating new branch"
# メインブランチに移動してリモートから最新を取得
echo "🔄 メインブランチから最新の変更を取得中..."
git checkout master 2>/dev/null || git checkout main
git pull origin master 2>/dev/null || git pull origin main
# 新しいブランチを作成
BRANCH_NAME="$1"
if [ -z "$BRANCH_NAME" ]; then
echo "❌ ブランチ名を指定してください"
echo "使用方法: /branch-create feature/your-feature-name"
exit 1
fi
echo "🌿 新しいブランチを作成中: $BRANCH_NAME"
git checkout -b "$BRANCH_NAME"
# stashした変更を適用
echo "📥 stashした変更を適用中..."
git stash pop
echo "✅ ブランチ作成完了: $BRANCH_NAME"
echo "📋 次のステップ:"
echo "1. 必要な変更を実装"
echo "2. /commit-create でコミット作成"
echo "3. /push-current でリモートにpush"
```
## 注意事項
- ブランチ名は意味のある名前にしてください
- feature/ プレフィックスを使用してください
- 既存のブランチ名と重複しないよう注意してください

View File

@@ -0,0 +1,31 @@
# 現在のブランチ表示コマンド
現在のブランチ名をシンプルに表示します。
## 使用方法
```bash
/branch-current
```
## 動作
現在のブランチ名を表示します。
## 実装
```bash
#!/bin/bash
# 現在のブランチ名を取得して表示
CURRENT_BRANCH=$(git branch --show-current)
echo "$CURRENT_BRANCH"
```
## 特徴
- **シンプル**: 現在のブランチ名のみを表示
- **高速**: 余計な処理なし
## 関連コマンド
- `/branch-main`: メインブランチに移動して更新
- `/branch-switch`: ブランチを切り替え
- `/branch-create`: 新しいブランチを作成
- `/commit`: 変更をコミット

212
commands/branch-main.md Normal file
View File

@@ -0,0 +1,212 @@
# メインブランチ最新化コマンド
メインブランチmain/masterに移動して最新の状態に更新します。
## 使用方法
```bash
/branch-main
```
## 動作
1. メインブランチ名を自動検出main または master
2. 作業中の変更を確認し、あれば自動的にstashで一時保存
3. メインブランチに切り替え
4. リモートから最新の変更を取得pull
5. stashした変更を自動復元
6. 更新後の状態を表示
## 実装
```bash
#!/bin/bash
# メインブランチ名を検出する関数
detect_main_branch() {
# リモートのメインブランチを確認
if git ls-remote --heads origin main >/dev/null 2>&1; then
echo "main"
elif git ls-remote --heads origin master >/dev/null 2>&1; then
echo "master"
else
# ローカルで確認
if git show-ref --verify --quiet refs/heads/main; then
echo "main"
elif git show-ref --verify --quiet refs/heads/master; then
echo "master"
else
echo ""
fi
fi
}
# 現在のブランチ名を取得
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
# メインブランチ名を検出
MAIN_BRANCH=$(detect_main_branch)
if [ -z "$MAIN_BRANCH" ]; then
echo "❌ メインブランチmain/masterが見つかりません"
echo ""
echo "💡 以下を確認してください:"
echo "- git remote -v でリモート設定を確認"
echo "- git branch -a でブランチ一覧を確認"
exit 1
fi
echo "🔄 メインブランチ更新処理を開始します"
echo ""
echo "📌 現在のブランチ: $CURRENT_BRANCH"
echo "🎯 メインブランチ: $MAIN_BRANCH"
# 作業ツリーに変更があるか確認
STASH_NEEDED=false
if ! git diff-index --quiet HEAD -- 2>/dev/null || [ -n "$(git ls-files --others --exclude-standard)" ]; then
echo ""
echo "📝 未コミットの変更を検出しました"
echo ""
echo "💡 変更内容:"
git status --short
echo ""
echo "🔄 変更を一時保存stashします..."
# stashにメッセージ付きで保存
STASH_MSG="Auto-stash by branch-main command from $CURRENT_BRANCH"
if git stash push -m "$STASH_MSG" --include-untracked; then
STASH_NEEDED=true
echo "✅ 変更を一時保存しました"
else
echo "❌ 変更の一時保存に失敗しました"
exit 1
fi
fi
# 既にメインブランチにいる場合
if [ "$CURRENT_BRANCH" = "$MAIN_BRANCH" ]; then
echo ""
echo "✅ 既に$MAIN_BRANCH ブランチにいます"
else
# メインブランチに切り替え
echo ""
echo "🔀 $MAIN_BRANCH ブランチに切り替え中..."
if ! git checkout $MAIN_BRANCH; then
echo "❌ ブランチの切り替えに失敗しました"
exit 1
fi
echo "$MAIN_BRANCH ブランチに切り替えました"
fi
# 最新の変更を取得
echo ""
echo "🌐 リモートから最新の変更を取得中..."
echo ""
if git pull origin $MAIN_BRANCH; then
echo ""
echo "✅ メインブランチの更新が完了しました!"
echo ""
# 更新後の状態を表示
echo "📊 更新後の状態:"
echo "- ブランチ: $MAIN_BRANCH"
echo "- 最新コミット: $(git log -1 --pretty=format:'%h - %s')"
# 元のブランチとの差分を表示(異なるブランチから来た場合)
if [ "$CURRENT_BRANCH" != "$MAIN_BRANCH" ]; then
echo ""
echo "📝 元のブランチ ($CURRENT_BRANCH) との差分:"
COMMITS_DIFF=$(git rev-list --count $CURRENT_BRANCH..$MAIN_BRANCH)
if [ "$COMMITS_DIFF" -gt 0 ]; then
echo "- $MAIN_BRANCH の方が $COMMITS_DIFF コミット進んでいます"
else
echo "- 差分はありません"
fi
echo ""
echo "💡 元のブランチに戻るには: git checkout $CURRENT_BRANCH"
fi
# stashした変更を復元
if [ "$STASH_NEEDED" = true ]; then
echo ""
echo "🔄 一時保存した変更を復元中..."
if git stash pop; then
echo "✅ 変更を復元しました"
echo ""
echo "📝 復元された変更:"
git status --short
else
echo "⚠️ 変更の復元中にコンフリクトが発生しました"
echo ""
echo "💡 手動で解決してください:"
echo "1. コンフリクトのあるファイルを編集"
echo "2. git add <ファイル名> でステージング"
echo "3. git stash drop で不要なstashを削除"
echo ""
echo "📋 stashリストを確認: git stash list"
fi
fi
else
echo ""
echo "❌ 更新中にエラーが発生しました"
echo ""
echo "💡 以下を確認してください:"
echo "- インターネット接続"
echo "- リモートリポジトリへのアクセス権限"
echo "- コンフリクトの有無"
# コンフリクトがある場合
if git status | grep -q "You have unmerged paths"; then
echo ""
echo "⚠️ マージコンフリクトが発生しています"
echo ""
echo "🔧 コンフリクトのあるファイル:"
git diff --name-only --diff-filter=U
echo ""
echo "📝 解決手順:"
echo "1. 上記のファイルを編集してコンフリクトを解決"
echo "2. git add <ファイル名> で解決済みファイルをステージング"
echo "3. git commit でマージを完了"
fi
# エラーが発生してもstashした変更を復元
if [ "$STASH_NEEDED" = true ]; then
echo ""
echo "🔄 一時保存した変更を復元中..."
if git stash pop; then
echo "✅ 変更を復元しました"
else
echo "⚠️ 変更の復元中にコンフリクトが発生しました"
echo "📋 stashリストを確認: git stash list"
fi
fi
exit 1
fi
echo ""
echo "💡 次のステップ:"
echo "- ブランチ一覧を確認: git branch"
echo "- 新しいブランチを作成: git checkout -b feature/new-feature"
echo "- 特定のブランチに切り替え: git checkout <ブランチ名>"
```
## 特徴
- **メインブランチ自動検出**: main/masterを自動的に判別
- **自動ブランチ切り替え**: メインブランチへの自動切り替え
- **自動stash機能**: 未コミットの変更を自動的に一時保存・復元
- **追跡ファイル対応**: 新規ファイルuntrackedも含めてstash
- **わかりやすい状態表示**: 更新後の状態と元のブランチとの差分を表示
- **視覚的なフィードバック**: 絵文字を使用した進行状況の表示
- **エラーハンドリング**: 各ステップでの適切なエラー処理とstash復元
## 注意事項
- 作業中の変更は自動的にstashされ、更新後に復元されます
- stash復元時にコンフリクトが発生した場合は手動解決が必要です
- 異なるブランチから実行した場合、元のブランチに戻る方法を表示します
- 更新後は必要に応じて新しいブランチを作成して作業を開始してください
## 関連コマンド
- `/branch-create`: 新しいブランチを作成
- `/branch-switch`: ブランチを切り替え
- `/commit`: 変更をコミット
- `/push-current`: 現在のブランチをプッシュ

126
commands/branch-switch.md Normal file
View File

@@ -0,0 +1,126 @@
# Branch Switch
指定したブランチに切り替えるカスタムコマンド。PR番号を指定することも可能。
```bash
# 引数チェック
if [ -z "$1" ]; then
echo "📋 利用可能なブランチ一覧:"
echo "=========================="
# ローカルブランチ一覧を表示
echo ""
echo "🏠 ローカルブランチ:"
git branch --format=' %(if)%(HEAD)%(then)* %(else) %(end)%(refname:short) %(upstream:track)'
echo ""
echo "☁️ リモートブランチ:"
git branch -r --format=' %(refname:short)' | grep -v 'HEAD'
echo ""
echo "使用方法: /branch-switch <ブランチ名 | PR番号>"
echo "例: /branch-switch feature/new-feature"
echo " /branch-switch main"
echo " /branch-switch 123 (PR #123のブランチに切り替え)"
exit 0
fi
INPUT="$1"
# PR番号かどうかをチェック数字のみの場合
if [[ "$INPUT" =~ ^[0-9]+$ ]]; then
PR_NUMBER="$INPUT"
echo "🔍 PR #$PR_NUMBER の情報を取得中..."
# GitHub CLIを使ってPR情報を取得
if ! command -v gh &> /dev/null; then
echo "❌ Error: GitHub CLI (gh) がインストールされていません"
echo "インストール方法: https://cli.github.com/"
exit 1
fi
# PR情報を取得
PR_INFO=$(gh pr view "$PR_NUMBER" --json headRefName,state,mergeable 2>/dev/null)
if [ $? -ne 0 ]; then
echo "❌ Error: PR #$PR_NUMBER が見つかりません"
exit 1
fi
# ブランチ名を抽出
BRANCH_NAME=$(echo "$PR_INFO" | jq -r '.headRefName')
PR_STATE=$(echo "$PR_INFO" | jq -r '.state')
if [ "$PR_STATE" = "CLOSED" ] || [ "$PR_STATE" = "MERGED" ]; then
echo "⚠️ 警告: PR #$PR_NUMBER は既に $PR_STATE されています"
echo "ブランチ '$BRANCH_NAME' に切り替えます..."
fi
echo "📋 PR #$PR_NUMBER のブランチ: $BRANCH_NAME"
else
BRANCH_NAME="$INPUT"
fi
# 現在のブランチを取得
CURRENT_BRANCH=$(git branch --show-current)
if [ "$CURRENT_BRANCH" = "$BRANCH_NAME" ]; then
echo "✅ すでに '$BRANCH_NAME' ブランチにいます"
exit 0
fi
# 未コミットの変更をチェック
if ! git diff --quiet || ! git diff --staged --quiet; then
echo "⚠️ 未コミットの変更があります:"
git status --short
echo ""
echo "📦 変更をstashに自動保存して切り替えます..."
git stash push -m "Auto-stash before switching to $BRANCH_NAME"
STASHED=true
fi
# ブランチが存在するかチェック
if git show-ref --verify --quiet "refs/heads/$BRANCH_NAME"; then
# ローカルブランチが存在する場合
echo "🔄 ローカルブランチ '$BRANCH_NAME' に切り替え中..."
git checkout "$BRANCH_NAME"
elif git show-ref --verify --quiet "refs/remotes/origin/$BRANCH_NAME"; then
# リモートブランチのみ存在する場合
echo "📥 リモートブランチ 'origin/$BRANCH_NAME' をチェックアウト中..."
git checkout -b "$BRANCH_NAME" "origin/$BRANCH_NAME"
else
# ブランチが存在しない場合
echo "❌ Error: ブランチ '$BRANCH_NAME' が見つかりません"
echo ""
echo "🌱 新しいブランチ '$BRANCH_NAME' を作成中..."
git checkout -b "$BRANCH_NAME"
fi
if [ $? -eq 0 ]; then
echo "✅ ブランチ '$BRANCH_NAME' に切り替えました"
# リモートの最新情報を取得
if git show-ref --verify --quiet "refs/remotes/origin/$BRANCH_NAME"; then
echo ""
echo "🔄 リモートとの差分をチェック中..."
git fetch origin "$BRANCH_NAME" --quiet
LOCAL=$(git rev-parse HEAD)
REMOTE=$(git rev-parse "origin/$BRANCH_NAME" 2>/dev/null)
if [ "$LOCAL" != "$REMOTE" ]; then
echo "⚠️ リモートブランチとの差分があります"
echo " 最新の変更を取得するには: git pull"
fi
fi
# stashがある場合は通知
if [ "$STASHED" = "true" ]; then
echo ""
echo "💡 stashに保存した変更を復元するには: git stash pop"
fi
else
echo "❌ ブランチの切り替えに失敗しました"
exit 1
fi
```

135
commands/ci-check.md Normal file
View File

@@ -0,0 +1,135 @@
# GitHub PR CI チェックコマンド
現在のブランチのPRのCI状態をチェックし、失敗の詳細を取得します。
## 使用方法
```bash
/ci-check
```
## 処理手順
1. 現在のブランチ名を取得
2. このブランチに関連するPRを検索
3. GitHub CLIを使用してCI状態をチェック
4. 失敗したチェックの詳細を表示
5. 失敗したチェックのログを表示
## 実装
まず、`git branch --show-current` を使用して現在のブランチを取得します。
### ステップ1: 現在のブランチとPRの取得
```bash
# 現在のブランチ名を取得
CURRENT_BRANCH=$(git branch --show-current)
echo "🌿 現在のブランチ: $CURRENT_BRANCH"
# このブランチのPRを検索
echo "🔍 ブランチに関連するPRを検索中..."
PR_INFO=$(gh pr list --head "$CURRENT_BRANCH" --json number,title,url 2>/dev/null)
if [ -z "$PR_INFO" ] || [ "$PR_INFO" = "[]" ]; then
echo "❌ 現在のブランチ ($CURRENT_BRANCH) に関連するPRが見つかりません"
echo "💡 まずPRを作成してください: /pr-create"
exit 1
fi
PR_NUMBER=$(echo "$PR_INFO" | jq -r '.[0].number')
PR_TITLE=$(echo "$PR_INFO" | jq -r '.[0].title')
PR_URL=$(echo "$PR_INFO" | jq -r '.[0].url')
echo "📋 PR情報:"
echo " 番号: #$PR_NUMBER"
echo " タイトル: $PR_TITLE"
echo " URL: $PR_URL"
```
### ステップ2: CI チェック状態の取得
```bash
# PRのチェック状態を取得
echo "🔍 CI チェック状態を確認中..."
CHECK_RUNS=$(gh pr checks "$PR_NUMBER" 2>/dev/null)
if [ $? -ne 0 ]; then
echo "❌ CI チェック情報を取得できませんでした"
echo "💡 GitHub CLIの権限を確認してください"
exit 1
fi
echo "$CHECK_RUNS"
```
### ステップ3: 失敗したチェックの詳細分析
```bash
# 失敗したチェックを特定
echo "🔍 失敗したチェックの詳細を分析中..."
# チェック結果を解析して失敗したものを特定
FAILED_CHECKS=$(echo "$CHECK_RUNS" | grep -E "(fail|error|✗)" || echo "")
if [ -z "$FAILED_CHECKS" ]; then
echo "✅ すべてのCIチェックが成功しています"
echo "🎉 PRの準備が整いました"
exit 0
fi
echo "❌ 失敗したチェック:"
echo "$FAILED_CHECKS"
echo ""
# 失敗したワークフローの詳細ログを取得
echo "📋 失敗の詳細ログ:"
WORKFLOW_RUNS=$(gh run list --branch "$CURRENT_BRANCH" --json databaseId,status,conclusion,name --limit 5)
echo "$WORKFLOW_RUNS" | jq -r '.[] | select(.conclusion == "failure") | "- \(.name): \(.conclusion)"'
```
### ステップ4: 失敗の種類別分析と提案
```bash
# 一般的な失敗パターンを分析
echo ""
echo "🔧 よくある修正方法:"
if echo "$FAILED_CHECKS" | grep -qi "lint"; then
echo "📝 リンティングエラー:"
echo " - /ci-fix を実行して自動修正を試行"
echo " - npm run lint または該当するlintコマンドを実行"
fi
if echo "$FAILED_CHECKS" | grep -qi "test"; then
echo "🧪 テストエラー:"
echo " - ローカルでテストを実行: npm test"
echo " - 失敗したテストを確認して修正"
fi
if echo "$FAILED_CHECKS" | grep -qi "build"; then
echo "🏗️ ビルドエラー:"
echo " - 依存関係を確認: npm install"
echo " - TypeScriptエラーを確認"
fi
if echo "$FAILED_CHECKS" | grep -qi "security"; then
echo "🔒 セキュリティ問題:"
echo " - 依存関係の脆弱性を確認"
echo " - npm audit fix を実行"
fi
echo ""
echo "🔄 次のステップ:"
echo "1. 上記の提案に従って問題を修正"
echo "2. /ci-fix を使用して自動修正を試行"
echo "3. 修正後に再度このコマンドで確認"
```
## 表示形式
結果を明確な形式で表示:
- 現在のブランチと関連PR
- 全体的なCI状態
- 失敗したチェック名
- エラーメッセージとログ
- よくある修正方法の提案
現在のブランチにPRが存在しない場合は、まずPRを作成するよう提案します。
## 注意事項
- GitHub CLIの認証が必要です
- プライベートリポジトリでは適切な権限が必要です
- CI システムが設定されている場合のみ有効です

219
commands/ci-fix.md Normal file
View File

@@ -0,0 +1,219 @@
# GitHub PR CI 修正コマンド
現在のブランチのPRのCI失敗を自動的に修正します。
## 使用方法
```bash
/ci-fix
```
## 処理手順
1. まずPR CIチェックを実行して失敗を特定
2. よくあるCI失敗パターンを分析
3. 適切な修正を自動的に適用
4. 可能な場合はローカルでテストを実行
5. 修正内容の概要を表示(コミットはしない)
## 実装
PR CIチェックコマンドを実行して失敗の詳細を取得することから開始します。
### ステップ1: CI失敗の分析
```bash
# まずCI状態をチェック
echo "🔍 CI失敗を分析中..."
CURRENT_BRANCH=$(git branch --show-current)
# PRの存在確認
PR_INFO=$(gh pr list --head "$CURRENT_BRANCH" --json number 2>/dev/null)
if [ -z "$PR_INFO" ] || [ "$PR_INFO" = "[]" ]; then
echo "❌ 現在のブランチにPRが見つかりません"
echo "💡 まず /pr-create でPRを作成してください"
exit 1
fi
PR_NUMBER=$(echo "$PR_INFO" | jq -r '.[0].number')
echo "📋 PR #$PR_NUMBER のCI失敗を修正します"
# チェック状態を取得
CHECK_RUNS=$(gh pr checks "$PR_NUMBER" 2>/dev/null)
FAILED_CHECKS=$(echo "$CHECK_RUNS" | grep -E "(fail|error|✗)" || echo "")
if [ -z "$FAILED_CHECKS" ]; then
echo "✅ CIに失敗はありません"
exit 0
fi
echo "❌ 検出された失敗:"
echo "$FAILED_CHECKS"
```
### ステップ2: 失敗の種類別自動修正
実装する一般的なCI修正
#### リンティングエラーの修正
```bash
if echo "$FAILED_CHECKS" | grep -qi "lint"; then
echo "📝 リンティングエラーを修正中..."
# よくあるリンターを実行
if [ -f "package.json" ]; then
echo "🔧 npm run lint --fix を実行中..."
npm run lint --fix 2>/dev/null || echo "npm lintコマンドが見つかりません"
fi
if command -v ruff >/dev/null 2>&1; then
echo "🔧 ruff check --fix を実行中..."
ruff check --fix .
fi
if command -v golangci-lint >/dev/null 2>&1; then
echo "🔧 golangci-lint を実行中..."
golangci-lint run --fix
fi
echo "✅ リンティング修正完了"
fi
```
#### 型エラーの修正
```bash
if echo "$FAILED_CHECKS" | grep -qi "type\|typescript"; then
echo "🏷️ 型エラーを分析中..."
if [ -f "tsconfig.json" ]; then
echo "🔧 TypeScript型チェックを実行中..."
npx tsc --noEmit 2>&1 | head -20
echo ""
echo "💡 型エラーの修正が必要です。上記のエラーを確認してください。"
fi
fi
```
#### テスト失敗の修正
```bash
if echo "$FAILED_CHECKS" | grep -qi "test"; then
echo "🧪 テスト失敗を分析中..."
# テストをローカルで実行
if [ -f "package.json" ]; then
echo "🔧 npm test を実行中..."
npm test 2>&1 | tail -20
elif [ -f "pytest.ini" ] || [ -f "pyproject.toml" ]; then
echo "🔧 pytest を実行中..."
python -m pytest -v --tb=short 2>&1 | tail -20
elif [ -f "go.mod" ]; then
echo "🔧 go test を実行中..."
go test ./... -v 2>&1 | tail -20
fi
echo ""
echo "💡 テスト失敗の詳細を確認して手動で修正してください"
fi
```
#### ビルド失敗の修正
```bash
if echo "$FAILED_CHECKS" | grep -qi "build"; then
echo "🏗️ ビルドエラーを修正中..."
# 依存関係の更新
if [ -f "package.json" ]; then
echo "📦 依存関係を更新中..."
npm install
echo "🔧 ビルドを試行中..."
npm run build 2>&1 | tail -20
fi
if [ -f "requirements.txt" ]; then
echo "📦 Python依存関係を更新中..."
pip install -r requirements.txt
fi
if [ -f "go.mod" ]; then
echo "📦 Go依存関係を更新中..."
go mod tidy
go build ./...
fi
fi
```
#### セキュリティ問題の修正
```bash
if echo "$FAILED_CHECKS" | grep -qi "security"; then
echo "🔒 セキュリティ問題を修正中..."
if [ -f "package.json" ]; then
echo "🔧 npm audit fix を実行中..."
npm audit fix
fi
if [ -f "requirements.txt" ]; then
echo "🔧 pip-audit を実行中..."
pip-audit --fix 2>/dev/null || echo "pip-audit が利用できません"
fi
echo "✅ セキュリティ修正完了"
fi
```
### ステップ3: 修正の検証と結果表示
```bash
# 修正内容を確認
echo ""
echo "📝 修正内容の確認:"
git status --porcelain
if [ -n "$(git status --porcelain)" ]; then
echo "✅ 修正が適用されました"
# ローカルテストを実行(可能な場合)
echo "🧪 修正の検証中..."
if [ -f "package.json" ]; then
npm test 2>/dev/null && echo "✅ テスト成功" || echo "⚠️ テストで問題が残っています"
fi
# 変更の詳細を表示
echo ""
echo "📋 修正されたファイル:"
git diff --name-only
echo ""
echo "📊 変更統計:"
git diff --stat
echo ""
echo "✅ CI修正が適用されました"
echo ""
echo "🔄 次のステップ:"
echo "1. 'git diff' で変更内容を詳細確認"
echo "2. 追加のテストが必要な場合は実行"
echo "3. /commit-create でコミット作成"
echo "4. /push-current でリモートにpush"
echo "5. 数分後に /ci-check で状態を確認"
else
echo " 自動修正可能な問題が見つかりませんでした"
echo "💡 手動での修正が必要です"
fi
```
## 各失敗タイプの修正方法
### 1. **リンティングエラー**: リンターを実行して自動修正
### 2. **型エラー**: TypeScript/型の問題を分析して修正
### 3. **テスト失敗**: テストをローカルで実行して失敗したテストを修正
### 4. **ビルド失敗**: 依存関係とビルド設定をチェック
### 5. **セキュリティ問題**: 依存関係を更新してセキュリティ脆弱性を修正
各失敗タイプについて:
1. エラーメッセージを解析して問題を理解
2. 利用可能なツールを使用して適切な修正を適用
3. 可能な場合はローカルで修正を検証
4. 修正内容を表示して次のステップを案内
修正後は、ユーザーが手動で内容を確認してからコミット・pushできるようになります。
## 注意事項
- すべてのCI失敗が自動修正できるわけではありません
- 複雑なロジックエラーは手動での修正が必要です
- 修正後は必ずローカルでテストを実行して検証してください
- 修正内容を確認してから /commit-create でコミットしてください
- セキュリティ関連の修正は慎重に確認してください

381
commands/commit-split.md Normal file
View File

@@ -0,0 +1,381 @@
# コミット分割コマンド
Gitの差分をもとに適切にコミットを分割します。ファイル単位や機能単位で論理的にコミットを分けることで、レビューしやすく意味のあるコミット履歴を作成します。
## 使用方法
```bash
/commit-split [ベースブランチ] [分割方式]
```
### パラメータ
- `ベースブランチ`: 比較対象のブランチ(省略時は`master`または`main`を自動検出)
- `分割方式`: `file`(ファイル単位)、`feature`(機能単位)、`interactive`(インタラクティブ)
## 処理手順
1. 現在の変更状況を確認
2. 差分の分析と分割方針の決定
3. インタラクティブな分割実行
4. 各コミットの作成と確認
## 実装
### ステップ1: 初期状態の確認
```bash
# 作業ディレクトリの状態を確認
echo "📊 現在の作業状況を確認中..."
git status --porcelain
# ステージされていない変更があるかチェック
UNSTAGED_CHANGES=$(git diff --name-only)
STAGED_CHANGES=$(git diff --cached --name-only)
if [ -n "$UNSTAGED_CHANGES" ] || [ -n "$STAGED_CHANGES" ]; then
echo "⚠️ 未コミットの変更があります"
echo "📝 ステージされていない変更: $(echo "$UNSTAGED_CHANGES" | wc -l) ファイル"
echo "📝 ステージされた変更: $(echo "$STAGED_CHANGES" | wc -l) ファイル"
else
echo "✅ 作業ディレクトリはクリーンです"
exit 0
fi
```
### ステップ2: ベースブランチの決定
```bash
# ベースブランチの自動検出または指定
BASE_BRANCH="${1:-}"
if [ -z "$BASE_BRANCH" ]; then
if git show-ref --verify --quiet refs/heads/master; then
BASE_BRANCH="master"
elif git show-ref --verify --quiet refs/heads/main; then
BASE_BRANCH="main"
else
echo "❌ ベースブランチを特定できません。明示的に指定してください。"
exit 1
fi
fi
echo "🎯 ベースブランチ: $BASE_BRANCH"
# ベースブランチとの差分を確認
CURRENT_BRANCH=$(git branch --show-current)
echo "🌿 現在のブランチ: $CURRENT_BRANCH"
```
### ステップ3: 差分の分析
```bash
# 変更されたファイルの一覧と統計
echo "📈 差分の分析中..."
CHANGED_FILES=$(git diff --name-only $BASE_BRANCH..HEAD 2>/dev/null || git diff --name-only)
if [ -z "$CHANGED_FILES" ]; then
echo "📝 ベースブランチとの差分がありません"
# 作業ディレクトリの変更のみ処理
CHANGED_FILES=$(git diff --name-only)
if [ -z "$CHANGED_FILES" ]; then
CHANGED_FILES=$(git diff --cached --name-only)
fi
fi
echo "📁 変更されたファイル一覧:"
echo "$CHANGED_FILES" | nl
# ファイルタイプ別の分類
DOCS_FILES=$(echo "$CHANGED_FILES" | grep -E '\.(md|txt|rst)$' || true)
CONFIG_FILES=$(echo "$CHANGED_FILES" | grep -E '\.(json|yaml|yml|toml|ini|conf)$' || true)
CODE_FILES=$(echo "$CHANGED_FILES" | grep -E '\.(js|ts|py|go|rs|java|c|cpp|php|rb)$' || true)
TEST_FILES=$(echo "$CHANGED_FILES" | grep -E '(test|spec)\.' || true)
echo ""
echo "📊 ファイルタイプ別統計:"
[ -n "$DOCS_FILES" ] && echo "📖 ドキュメント: $(echo "$DOCS_FILES" | wc -l) ファイル"
[ -n "$CONFIG_FILES" ] && echo "⚙️ 設定ファイル: $(echo "$CONFIG_FILES" | wc -l) ファイル"
[ -n "$CODE_FILES" ] && echo "💻 コードファイル: $(echo "$CODE_FILES" | wc -l) ファイル"
[ -n "$TEST_FILES" ] && echo "🧪 テストファイル: $(echo "$TEST_FILES" | wc -l) ファイル"
```
### ステップ4: 分割方式の決定
```bash
SPLIT_MODE="${2:-file}"
case "$SPLIT_MODE" in
"file")
echo "📂 ファイル単位での分割を実行します"
commit_by_file
;;
"feature")
echo "🎯 機能単位での分割を実行します"
commit_by_feature
;;
"interactive"|*)
echo "🤝 インタラクティブ分割を実行します"
commit_interactive
;;
esac
```
### ステップ5: ファイル単位分割の実装
```bash
commit_by_file() {
echo "$CHANGED_FILES" | while read -r file; do
if [ -n "$file" ]; then
echo ""
echo "📝 処理中: $file"
# ファイルの変更内容を表示
git diff --stat "$file" 2>/dev/null || git diff --cached --stat "$file" 2>/dev/null || true
# コミットメッセージの自動生成
FILE_EXT="${file##*.}"
DIR_NAME=$(dirname "$file")
FILE_NAME=$(basename "$file")
# ファイルタイプに基づいたプレフィックス
if echo "$file" | grep -q -E '\.(md|txt|rst)$'; then
PREFIX="docs"
elif echo "$file" | grep -q -E '\.(json|yaml|yml|toml|ini|conf)$'; then
PREFIX="config"
elif echo "$file" | grep -q -E '(test|spec)\.'; then
PREFIX="test"
else
PREFIX="feat"
fi
COMMIT_MSG="$PREFIX: update $FILE_NAME"
# 自動でコミット(確認なし)
echo "💬 提案されたコミットメッセージ: $COMMIT_MSG"
git add "$file"
git commit -m "$COMMIT_MSG"
echo "✅ コミット完了: $file"
fi
done
}
```
### ステップ6: 機能単位分割の実装
```bash
commit_by_feature() {
# ディレクトリ構造に基づいた機能別グループ化
echo "🔍 機能別にファイルをグループ化中..."
# ディレクトリごとにファイルをグループ化
DIRECTORIES=$(echo "$CHANGED_FILES" | xargs dirname | sort | uniq)
echo "$DIRECTORIES" | while read -r dir; do
if [ -n "$dir" ]; then
DIR_FILES=$(echo "$CHANGED_FILES" | grep "^$dir/")
if [ -n "$DIR_FILES" ]; then
echo ""
echo "📁 ディレクトリ: $dir"
echo "$DIR_FILES" | sed 's/^/ - /'
# ディレクトリ名に基づいたコミットメッセージ
case "$dir" in
"src"|"lib"|"app")
PREFIX="feat"
;;
"test"|"tests"|"__tests__")
PREFIX="test"
;;
"docs"|"doc")
PREFIX="docs"
;;
"config"|".github")
PREFIX="config"
;;
*)
PREFIX="update"
;;
esac
COMMIT_MSG="$PREFIX: update $dir module"
echo "💬 提案されたコミットメッセージ: $COMMIT_MSG"
echo "$DIR_FILES" | xargs git add
git commit -m "$COMMIT_MSG"
echo "✅ コミット完了: $dir"
fi
fi
done
}
```
### ステップ7: インタラクティブ分割の実装
```bash
commit_interactive() {
echo "🎮 自動モードでコミットを分割します"
# 現在の状態を確認
REMAINING_UNSTAGED=$(git diff --name-only)
REMAINING_STAGED=$(git diff --cached --name-only)
if [ -z "$REMAINING_UNSTAGED" ] && [ -z "$REMAINING_STAGED" ]; then
echo "📝 変更がありません"
return
fi
# 全ファイルをステージして一度にコミット
git add .
commit_staged_changes
echo "🎉 すべての変更が処理されました!"
}
select_files_for_staging() {
ALL_CHANGED=$(git status --porcelain | awk '{print $2}')
if [ -z "$ALL_CHANGED" ]; then
echo "📝 変更されたファイルがありません"
return
fi
echo "📁 変更されたファイル一覧:"
echo "$ALL_CHANGED" | nl
echo ""
# 全ファイルを自動でステージ
echo "$ALL_CHANGED" | while read -r file; do
if [ -n "$file" ]; then
git add "$file"
echo "✅ ステージ完了: $file"
fi
done
}
commit_staged_changes() {
STAGED=$(git diff --cached --name-only)
if [ -z "$STAGED" ]; then
echo "📦 ステージされた変更がありません"
return
fi
echo "📦 ステージされたファイル:"
echo "$STAGED" | sed 's/^/ - /'
echo ""
# 自動でコミット
commit_msg="update: staged changes"
git commit -m "$commit_msg"
echo "✅ コミット完了!"
}
show_diff_summary() {
echo "📊 変更サマリー:"
git diff --stat
echo ""
git diff --cached --stat
echo ""
# 詳細な差分を自動的に表示
echo "📖 詳細な差分:"
git diff
git diff --cached
}
auto_push_changes() {
# 現在のブランチ名を取得
CURRENT_BRANCH=$(git branch --show-current)
echo "📤 リモートブランチにプッシュ中..."
# リモートブランチが存在するかチェック
if git ls-remote --heads origin "$CURRENT_BRANCH" | grep -q "$CURRENT_BRANCH"; then
# リモートブランチが存在する場合は通常のpush
git push
if [ $? -eq 0 ]; then
echo "✅ プッシュ完了: $CURRENT_BRANCH"
else
echo "⚠️ プッシュでエラーが発生しました"
fi
else
# リモートブランチが存在しない場合は -u オプション付きでpush
git push -u origin "$CURRENT_BRANCH"
if [ $? -eq 0 ]; then
echo "✅ 新しいブランチを作成してプッシュ完了: $CURRENT_BRANCH"
else
echo "⚠️ プッシュでエラーが発生しました"
fi
fi
}
show_help() {
echo "📚 コミット分割ヘルプ"
echo ""
echo "🎯 目的: 大きな変更を論理的に分割して複数のコミットに分ける"
echo ""
echo "💡 推奨される分割方針:"
echo " - 📁 ファイルタイプ別(設定、ドキュメント、コード、テスト)"
echo " - 🎯 機能別(新機能、バグ修正、リファクタリング)"
echo " - 📦 影響範囲別フロントエンド、バックエンド、DB"
echo ""
echo "🔧 便利なGitコマンド:"
echo " - git add -p : パッチ単位での選択的ステージング"
echo " - git diff --cached : ステージされた変更の確認"
echo " - git reset <file> : ファイルのアンステージ"
echo " - git status : 現在の状態確認"
echo ""
echo "📤 プッシュ機能:"
echo " - 各コミット後に個別でプッシュするか選択可能"
echo " - 最終処理で全てのコミットを一括プッシュ"
}
```
### ステップ8: 完了処理とプッシュ
```bash
# 最終確認と統計
echo ""
echo "🎉 コミット分割が完了しました!"
echo ""
echo "📈 作成されたコミット:"
git log --oneline -10
echo ""
echo "📤 自動プッシュを実行します..."
# 現在のブランチ名を取得
CURRENT_BRANCH=$(git branch --show-current)
# リモートブランチが存在するかチェック
if git ls-remote --heads origin "$CURRENT_BRANCH" | grep -q "$CURRENT_BRANCH"; then
# リモートブランチが存在する場合は通常のpush
git push
echo "✅ プッシュ完了: $CURRENT_BRANCH"
else
# リモートブランチが存在しない場合は -u オプション付きでpush
git push -u origin "$CURRENT_BRANCH"
echo "✅ 新しいブランチを作成してプッシュ完了: $CURRENT_BRANCH"
fi
echo ""
echo "🚀 すべてのコミットがリモートに反映されました!"
```
## 重要なルール
- **段階的なコミット**: 関連する変更をまとめて、レビューしやすい単位でコミット
- **意味のあるメッセージ**: 各コミットが何を変更したかを明確に記述
- **ファイルタイプの考慮**: 設定ファイル、ドキュメント、コード、テストを適切に分離
- **レビュー性の向上**: 1つのコミットで1つの論理的変更を実現
- **自動プッシュ**: 各コミット後にプッシュ選択可能、最終的に全コミットをリモートに反映
## 使用例
### ファイル単位での分割
```bash
/commit-split master file
```
### 機能単位での分割
```bash
/commit-split main feature
```
### インタラクティブ分割
```bash
/commit-split
```
## 注意事項
- 実行前に重要な変更はバックアップを取ってください
- `git add -p` を使用する際は、パッチの内容をよく確認してください
- 各コミット後にプッシュするかどうかを選択できます
- 最終的にすべてのコミットがリモートに反映されます
- リモートにプッシュ済みのコミットは分割しないでください

72
commands/commit-staged.md Normal file
View File

@@ -0,0 +1,72 @@
# /commit-staged
## 概要
stageされたファイルのみをコミットするためのコマンドです。適切なコミットメッセージを自動生成し、安全にコミットを実行します。
## 動作
1. `git status`でstageされたファイルを確認
2. stageされたファイルがない場合は警告を表示して終了
3. `git diff --cached`でstageされた変更内容を確認
4. 最近のコミットメッセージを参照してスタイルを把握
5. 変更内容に基づいて適切なコミットメッセージを生成
6. コミットを実行
7. コミット結果を確認
## 実装手順
### ステップ1: 事前チェック
```bash
# stageされたファイルを確認
git status --porcelain | grep "^[MADRCU]"
```
- stageされたファイルがない場合は終了
- unstageされた変更があっても無視stageされたもののみを対象
### ステップ2: 変更内容の分析
```bash
# stageされた変更の詳細を取得
git diff --cached
# 最近のコミットメッセージのスタイルを確認
git log --oneline -10
```
### ステップ3: コミットメッセージの生成
変更内容を分析して以下の形式でメッセージを生成:
- **feat**: 新機能の追加
- **fix**: バグ修正
- **refactor**: リファクタリング
- **docs**: ドキュメントの更新
- **style**: コードスタイルの修正
- **test**: テストの追加・修正
- **chore**: その他の変更
### ステップ4: コミット実行
```bash
# HEREDOCを使用してコミットメッセージを適用
git commit -m "$(cat <<'EOF'
[生成されたコミットメッセージ]
EOF
)"
```
### ステップ5: 結果確認
```bash
# コミット結果を確認
git status
git log --oneline -1
```
## 注意事項
- stageされていないファイルは含まれません
- 機密情報が含まれていないかチェックします
- プリコミットフックが失敗した場合は再試行を提案します
- pushは自動実行しませんユーザーの明示的な指示を待つ
- 空のコミットは作成しません
## 使用例
```
/commit-staged
```
このコマンドにより、stageされたファイルのみが適切なコミットメッセージと共にコミットされます。

23
commands/commit.md Normal file
View File

@@ -0,0 +1,23 @@
# commitメッセージを作成
現在の変更をコミットし、自動的にリモートブランチにプッシュします。
## 実行手順
1. `git status`でファイルを確認
2. [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/)に従ってコミットを実行
3. 自動的に`git push`でリモートブランチに反映
## 形式の指定
- type(scope): subject の形式に従う
- タイトルは50文字以内、本文は72文字程度で改行
- 動詞は原形を使用add, fix, updateなど
- scope は原則記述するが、適切なものがない場合は省略可
- コミットメッセージは小文字で始める
## 実装とテストが含まれる場合の優先ルール
- 実装とテストコードが含まれている場合、typeはtestよりもfeat/fixを優先する
## プッシュの動作
- コミット成功後、自動的に`git push`を実行
- ブランチがリモートに存在しない場合は`git push -u origin <branch_name>`を実行
- プッシュエラー時は適切なエラーメッセージを表示

225
commands/dp-ci-fix.md Normal file
View File

@@ -0,0 +1,225 @@
# Dependabot PR CI修正コマンド
DependabotのプルリクエストでCIエラーが発生しているものを自動的に修正します。
## 使用方法
```bash
/dp-ci-fix
```
## 処理手順
1. Dependabotが作成したPR一覧を取得
2. CIが失敗しているPRを特定
3. 各失敗PRに対してClaudeが修正を実行
4. 修正結果をレポート
## 実装
### ステップ1: Dependabot PRとCIステータスの取得
```bash
# GitHub CLIの確認
if ! command -v gh &> /dev/null; then
echo "❌ Error: GitHub CLI (gh) がインストールされていません"
echo "インストール方法: https://cli.github.com/"
exit 1
fi
echo "🤖 Dependabot PRのCIエラーを確認中..."
echo "========================================"
# Dependabotが作成したPRを取得
DEPENDABOT_PRS=$(gh pr list --state open --author "app/dependabot" --json number,title,headRefName,statusCheckRollup)
if [ "$DEPENDABOT_PRS" = "[]" ]; then
echo "✨ Dependabotのオープン中のPRはありません"
exit 0
fi
# CIが失敗しているPRをフィルタリング
FAILED_PRS=$(echo "$DEPENDABOT_PRS" | jq -r '.[] | select(.statusCheckRollup != null) | select(.statusCheckRollup | map(select(.conclusion == "FAILURE")) | length > 0) | @json')
if [ -z "$FAILED_PRS" ]; then
echo "✅ CIエラーのあるDependabot PRはありません"
exit 0
fi
FAILED_COUNT=$(echo "$FAILED_PRS" | wc -l | tr -d ' ')
echo "❌ CIエラーが見つかりました: ${FAILED_COUNT}件のPR"
echo ""
```
### ステップ2: 各失敗PRの修正
```bash
# 元のブランチを保存
ORIGINAL_BRANCH=$(git branch --show-current)
echo "💾 元のブランチ: $ORIGINAL_BRANCH"
echo ""
# 修正結果を記録
SUCCESS_PRS=()
FAILED_FIX_PRS=()
# 各PRを処理
echo "$FAILED_PRS" | while IFS= read -r pr_json; do
PR_NUMBER=$(echo "$pr_json" | jq -r '.number')
PR_TITLE=$(echo "$pr_json" | jq -r '.title')
PR_BRANCH=$(echo "$pr_json" | jq -r '.headRefName')
echo "🔧 PR #${PR_NUMBER} を修正中: ${PR_TITLE}"
echo " ブランチ: ${PR_BRANCH}"
# ブランチをチェックアウト
if ! git fetch origin "$PR_BRANCH" 2>/dev/null; then
echo " ❌ ブランチの取得に失敗"
FAILED_FIX_PRS+=("#${PR_NUMBER}")
continue
fi
if ! git checkout "$PR_BRANCH" 2>/dev/null; then
echo " ❌ チェックアウトに失敗"
FAILED_FIX_PRS+=("#${PR_NUMBER}")
continue
fi
# 依存関係の再インストールClaudeがリポジトリを確認して適切なコマンドを実行
echo " 📦 依存関係を再インストール中..."
echo " Claudeがリポジトリの構成を確認して適切なインストールコマンドを実行します"
# CI失敗の種類を確認
FAILED_CHECKS=$(gh pr checks "$PR_NUMBER" 2>/dev/null | grep -E "(fail|error|✗)" || echo "")
echo " 失敗したチェック:"
echo "$FAILED_CHECKS" | while IFS= read -r check; do
echo " - $check"
done
# Claudeに修正を依頼
echo " 🤖 Claudeに修正を依頼します"
echo ""
echo " 失敗したチェック内容に基づいて、以下の修正を行ってください:"
echo "$FAILED_CHECKS"
echo ""
echo " ⚠️ 重要な制約:"
echo " - lintエラー: できる限りignoreコメントを使わず実際のコードを修正すること"
echo " - リポジトリの構成を確認して適切な修正方法を選択すること"
echo ""
# メジャーバージョンアップの確認
PR_DIFF=$(gh pr diff "$PR_NUMBER" 2>/dev/null || echo "")
if echo "$PR_DIFF" | grep -qE '^\-.*"[^"]+": *"[0-9]+\.[0-9]+'; then
OLD_VER=$(echo "$PR_DIFF" | grep -E '^\-.*"[^"]+": *"[0-9]+\.[0-9]+' | head -1 | sed -E 's/.*"([0-9]+)\..*/\1/')
NEW_VER=$(echo "$PR_DIFF" | grep -E '^\+.*"[^"]+": *"[0-9]+\.[0-9]+' | head -1 | sed -E 's/.*"([0-9]+)\..*/\1/')
PACKAGE=$(echo "$PR_DIFF" | grep -E '^\+.*"[^"]+": *"[0-9]+\.[0-9]+' | head -1 | sed -E 's/.*"([^"]+)".*/\1/')
if [ "$OLD_VER" != "$NEW_VER" ] && [ -n "$PACKAGE" ]; then
echo " ⚠️ メジャーバージョンアップ: $PACKAGE ($OLD_VER.x → $NEW_VER.x)"
echo " 🔍 マイグレーションガイドを確認中..."
/gemini-search "$PACKAGE version $NEW_VER migration guide" 2>/dev/null | head -10 || true
echo ""
fi
fi
# 変更があればコミット
if [ -n "$(git status --porcelain)" ]; then
echo " 💾 変更をコミット中..."
git add .
git commit -m "fix: CI errors for dependabot PR
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>"
# プッシュ
echo " 📤 リモートにプッシュ中..."
if git push origin "$PR_BRANCH"; then
echo " ✅ プッシュ完了"
# CI結果を待機して確認
echo " ⏳ CI実行を待機中最大5分..."
sleep 30 # 初回実行開始を待つ
TIMEOUT=270 # 残り4分30秒
INTERVAL=30
CI_PASSED=false
while [ $TIMEOUT -gt 0 ]; do
CI_STATUS=$(gh pr checks "$PR_NUMBER" --json state,conclusion 2>/dev/null || echo "")
# すべてのチェックが完了しているか確認
if echo "$CI_STATUS" | jq -e 'all(.state == "COMPLETED")' >/dev/null 2>&1; then
# すべて成功しているか確認
if echo "$CI_STATUS" | jq -e 'all(.conclusion == "SUCCESS")' >/dev/null 2>&1; then
echo " ✅ CI成功"
CI_PASSED=true
SUCCESS_PRS+=("#${PR_NUMBER}: ${PR_TITLE}")
break
else
echo " ❌ CI失敗"
FAILED_FIX_PRS+=("#${PR_NUMBER}: ${PR_TITLE} (CI失敗)")
break
fi
fi
sleep $INTERVAL
TIMEOUT=$((TIMEOUT - INTERVAL))
done
if [ "$CI_PASSED" = false ] && [ $TIMEOUT -le 0 ]; then
echo " ⏱️ CI確認タイムアウト"
FAILED_FIX_PRS+=("#${PR_NUMBER}: ${PR_TITLE} (CI確認中)")
fi
else
echo " ❌ プッシュに失敗"
FAILED_FIX_PRS+=("#${PR_NUMBER}: ${PR_TITLE}")
fi
else
echo " 自動修正可能な変更なし"
FAILED_FIX_PRS+=("#${PR_NUMBER}: ${PR_TITLE} (要手動修正)")
fi
echo ""
done
# 元のブランチに戻る
echo "🔙 元のブランチに戻ります: $ORIGINAL_BRANCH"
git checkout "$ORIGINAL_BRANCH"
```
### ステップ4: 結果レポート
```bash
echo ""
echo "📊 修正結果レポート"
echo "========================================"
if [ ${#SUCCESS_PRS[@]} -gt 0 ]; then
echo ""
echo "✅ 修正成功 (${#SUCCESS_PRS[@]}件):"
for pr in "${SUCCESS_PRS[@]}"; do
echo " - $pr"
done
fi
if [ ${#FAILED_FIX_PRS[@]} -gt 0 ]; then
echo ""
echo "❌ 修正失敗または手動対応が必要 (${#FAILED_FIX_PRS[@]}件):"
for pr in "${FAILED_FIX_PRS[@]}"; do
echo " - $pr"
done
fi
echo ""
echo "🔄 次のステップ:"
echo "1. 数分待ってCIが再実行されるのを確認"
echo "2. 手動対応が必要なPRは個別に確認"
echo "3. /pr-list でPRの状態を確認"
echo ""
echo "✅ Dependabot PR CI修正処理が完了しました"
```
## 注意事項
- GitHub CLIが必要です
- Claudeがリポジトリを確認して修正方法を判断します
- すべてのエラーが自動修正できるわけではありません
- 複雑なエラーは手動での修正が必要です
- 修正後、CIの再実行には数分かかる場合があります

127
commands/gemini-search.md Normal file
View File

@@ -0,0 +1,127 @@
# Gemini ウェブ検索コマンド
Gemini AIを使用してGoogle検索を実行し、結果を要約して表示します。
## 使用方法
```bash
/gemini-search [検索クエリ]
```
## 例
```bash
/gemini-search "Claude Code の最新機能"
/gemini-search "TypeScript 5.0 新機能"
/gemini-search "Next.js App Router ベストプラクティス"
```
## 実装
```bash
#!/bin/bash
# gemini-cliがインストールされているかチェック
if ! command -v gemini &> /dev/null; then
echo "❌ gemini-cliがインストールされていません"
echo ""
echo "📦 インストール手順:"
echo "npm install -g @google/gemini-cli"
echo ""
echo "🔑 初期化手順:"
echo "gemini"
echo ""
echo "詳細: https://zenn.dev/mizchi/articles/gemini-cli-for-google-search"
exit 1
fi
# 検索クエリが指定されているかチェック
if [ -z "$1" ]; then
echo "❌ 検索クエリを指定してください"
echo ""
echo "使用方法: /gemini-search [検索クエリ]"
echo "例: /gemini-search \"Claude Code の最新機能\""
exit 1
fi
# 検索クエリを組み立て
SEARCH_QUERY="$*"
echo "🔍 検索中: $SEARCH_QUERY"
echo ""
# 一時ファイルで結果をキャプチャ
TEMP_FILE=$(mktemp)
# Gemini AIでウェブ検索を実行
SEARCH_PROMPT="Webで「$SEARCH_QUERY」について調べて、以下の形式で回答してください:
## 🔍 検索結果の要約
[検索結果の主要なポイントを3-5個の箇条書きで]
## 📝 詳細情報
[重要な詳細情報や具体的な内容]
## 🔗 参考リンク
[関連する重要なURLがあれば記載]
## 📅 最新性
[情報の時期や最新性について]
回答は日本語で、読みやすく整理して提供してください。"
echo "🤖 Gemini AIで検索結果を分析中..."
# 検索を実行し、結果を一時ファイルに保存
if gemini -p "$SEARCH_PROMPT" > "$TEMP_FILE" 2>&1; then
echo ""
echo "=" | tr -d '\n' | while read; do printf "=%.0s" {1..60}; done
echo ""
echo "📊 検索結果まとめ"
echo "=" | tr -d '\n' | while read; do printf "=%.0s" {1..60}; done
echo ""
# 結果を表示
cat "$TEMP_FILE"
echo ""
echo "=" | tr -d '\n' | while read; do printf "=%.0s" {1..60}; done
echo ""
echo "✅ 検索完了 - クエリ: \"$SEARCH_QUERY\""
echo "💡 より詳細な情報が必要な場合は、具体的なキーワードで再検索してください"
else
echo ""
echo "❌ 検索に失敗しました"
echo ""
echo "💡 トラブルシューティング:"
echo "- gemini-cliの認証状態を確認: gemini"
echo "- インターネット接続を確認"
echo "- 検索クエリを変更して再試行"
# エラー内容も表示
if [ -s "$TEMP_FILE" ]; then
echo ""
echo "エラー詳細:"
cat "$TEMP_FILE"
fi
fi
# 一時ファイルを削除
rm -f "$TEMP_FILE"
```
## 特徴
- **リアルタイム検索**: Googleの最新情報にアクセス
- **AI要約**: Gemini AIが検索結果を整理して表示
- **統合された結果表示**: 検索結果を見やすい形式でまとめて表示
- **視覚的な区切り**: 結果の開始と終了を明確に示すボーダー表示
- **日本語対応**: 日本語クエリでの検索に最適化
- **エラーハンドリング**: 適切なエラーメッセージとトラブルシューティング
- **一時ファイル管理**: 結果を安全にキャプチャして表示
## 注意事項
- gemini-cliの初回使用時はGoogleアカウントでの認証が必要です
- 検索結果の品質はGemini AIの解析能力に依存します
- 大量の検索を行う場合はAPI使用量にご注意ください
## 関連コマンド
- `/pr-create`: プルリクエスト作成
- `/commit`: コミットとプッシュ
- `/review-diff`: コード差分レビュー

50
commands/kiro.md Normal file
View File

@@ -0,0 +1,50 @@
# /kiro
## 概要
Kiroスペックから実装を行うためのコマンドです。`.kiro/specs`ディレクトリ内のスペックを一覧表示し、選択したスペックの実装を開始します。
## 動作
1. `.kiro/specs`ディレクトリ内の全スペックを作成日時の降順で一覧表示
2. ユーザーが番号を選択
3. 選択されたスペックの`requirements.md`を読み込み
4. 必要に応じて`design.md``tasks.md`も参照
5. 実装を開始
## 実装手順
### ステップ1: スペック一覧の表示
```bash
# .kiro/specs配下のrequirements.mdファイルを検索し、作成日時でソート
# macOSの場合
find .kiro/specs -name "requirements.md" -type f -exec stat -f "%Sm %N" -t "%Y/%m/%d %H:%M" {} \; | sort -r
# Linuxの場合
find .kiro/specs -name "requirements.md" -type f -exec stat --format="%y %n" {} \; | sort -r
```
各スペックについて以下を表示:
- 番号(選択用)
- スペック名(ディレクトリ名から取得)
- 作成日時YYYY/MM/DD形式
- 概要requirements.mdの最初の段落から抽出
### ステップ2: スペック選択
ユーザーに番号入力を促し、対応するスペックを選択
### ステップ3: スペック内容の読み込み
選択されたスペックのディレクトリから以下のファイルを読み込み:
- `requirements.md`(必須): 要件定義
- `design.md`(存在する場合): 設計詳細
- `tasks.md`(存在する場合): タスクリスト
### ステップ4: 実装開始
1. TodoWriteツールを使用してタスクリストを作成
- tasks.mdがある場合はそれを基に作成
- ない場合はrequirements.mdから主要タスクを抽出
2. 各タスクを順番に実装
3. 必要に応じてテストとリントを実行
## 注意事項
- スペックファイルが存在しない場合は適切なエラーメッセージを表示
- 実装前に現在のgitブランチを確認し、必要に応じて新しいブランチを作成することを提案
- 実装完了後は自動的にコミットは行わない(ユーザーの明示的な指示を待つ)

181
commands/pr-create.md Normal file
View File

@@ -0,0 +1,181 @@
# プルリクエスト作成コマンド
現在のブランチからプルリクエストを作成します。
## 使用方法
```bash
/pr-create [タイトル] [説明]
```
## 処理手順
1. 現在のブランチの変更をpushまだpushされていない場合
2. PRテンプレートを読み込み存在する場合
3. コミット履歴から適切なタイトルと説明を生成
4. ドラフトPRとして作成
5. PR URLを表示
## 実装
### ステップ1: ブランチの状態確認
```bash
# 現在のブランチ名を取得
CURRENT_BRANCH=$(git branch --show-current)
echo "🌿 現在のブランチ: $CURRENT_BRANCH"
# リモートブランチとの同期状態を確認
git fetch origin
# pushが必要かチェック
UNPUSHED_COMMITS=$(git rev-list --count origin/$CURRENT_BRANCH..$CURRENT_BRANCH 2>/dev/null || echo "new")
if [ "$UNPUSHED_COMMITS" = "new" ] || [ "$UNPUSHED_COMMITS" -gt 0 ]; then
echo "📤 リモートブランチにpushします..."
git push -u origin $CURRENT_BRANCH
else
echo "✅ ブランチは既にpushされています"
fi
```
### ステップ2: PRテンプレートの確認
```bash
# PRテンプレートが存在するかチェック
PR_TEMPLATE_FILE=""
if [ -f ".github/PULL_REQUEST_TEMPLATE.md" ]; then
PR_TEMPLATE_FILE=".github/PULL_REQUEST_TEMPLATE.md"
echo "📋 PRテンプレートを発見: $PR_TEMPLATE_FILE"
elif [ -f ".github/pull_request_template.md" ]; then
PR_TEMPLATE_FILE=".github/pull_request_template.md"
echo "📋 PRテンプレートを発見: $PR_TEMPLATE_FILE"
else
echo "📝 PRテンプレートが見つかりません。デフォルトの形式を使用します。"
fi
```
### ステップ3: PRタイトルと説明の生成
```bash
# コミット履歴からタイトルを生成(引数で指定されていない場合)
if [ -z "$1" ]; then
# 最新のコミットメッセージをタイトルに使用
PR_TITLE=$(git log -1 --pretty=format:"%s")
echo "💡 コミットメッセージからタイトルを生成: $PR_TITLE"
else
PR_TITLE="$1"
echo "📝 指定されたタイトル: $PR_TITLE"
fi
# PRの説明を生成
if [ -z "$2" ]; then
echo "📝 PR説明を生成中..."
# mainブランチからの変更履歴を取得
COMMITS=$(git log --oneline master..$CURRENT_BRANCH 2>/dev/null || git log --oneline main..$CURRENT_BRANCH 2>/dev/null || git log --oneline -5)
# 変更されたファイルの一覧を取得
CHANGED_FILES=$(git diff --name-only master..$CURRENT_BRANCH 2>/dev/null || git diff --name-only main..$CURRENT_BRANCH 2>/dev/null || git diff --name-only HEAD~5..HEAD)
if [ -n "$PR_TEMPLATE_FILE" ]; then
echo "📋 PRテンプレートをベースに説明を生成します"
# PRテンプレートをベースとして使用
PR_BODY=$(cat "$PR_TEMPLATE_FILE")
# テンプレート内の特定のプレースホルダーを置換
# 概要セクションに変更内容を自動挿入
if echo "$PR_BODY" | grep -q "## 概要\|## Overview\|## Summary"; then
# 概要セクションの後に変更内容を挿入
PR_BODY=$(echo "$PR_BODY" | sed '/## 概要\|## Overview\|## Summary/a\\n**このPRの主な変更:**')
if [ -n "$COMMITS" ]; then
COMMIT_LIST=""
echo "$COMMITS" | while read commit; do
COMMIT_LIST="$COMMIT_LIST- $commit\n"
done
PR_BODY="$PR_BODY\n$COMMIT_LIST"
fi
fi
# 変更されたファイルの情報を追加(テンプレートに該当セクションがない場合)
if ! echo "$PR_BODY" | grep -q "変更.*ファイル\|Changed.*Files\|Files.*Changed"; then
if [ -n "$CHANGED_FILES" ]; then
PR_BODY="$PR_BODY\n\n## 変更されたファイル\n"
echo "$CHANGED_FILES" | while read file; do
PR_BODY="$PR_BODY- $file\n"
done
fi
fi
else
echo "📝 デフォルト形式でPR説明を生成します"
# PRテンプレートがない場合のデフォルト形式
PR_BODY="## 概要\n\nこの変更の目的と概要を記述してください\n\n"
if [ -n "$COMMITS" ]; then
PR_BODY="$PR_BODY## 変更一覧\n"
echo "$COMMITS" | while read commit; do
PR_BODY="$PR_BODY- $commit\n"
done
PR_BODY="$PR_BODY\n"
fi
if [ -n "$CHANGED_FILES" ]; then
PR_BODY="$PR_BODY## 変更されたファイル\n"
echo "$CHANGED_FILES" | while read file; do
PR_BODY="$PR_BODY- $file\n"
done
PR_BODY="$PR_BODY\n"
fi
PR_BODY="$PR_BODY## テスト計画\n- [ ] 手動テスト実行\n- [ ] 自動テスト確認\n\n## チェックリスト\n- [ ] コードレビュー準備完了\n- [ ] ドキュメント更新(必要に応じて)\n- [ ] 破壊的変更の確認"
fi
else
PR_BODY="$2"
echo "📝 指定された説明を使用"
fi
```
### ステップ4: PRの作成
```bash
# ドラフトPRとして作成
echo "🚀 ドラフトPRを作成中..."
# PRを作成HEREDOCを使用して適切にフォーマット
# bodyにHTMLコメントが含まれる場合の対応
PR_BODY_FILE=$(mktemp)
echo -e "$PR_BODY" > "$PR_BODY_FILE"
gh pr create --draft --title "$PR_TITLE" --body-file "$PR_BODY_FILE"
rm -f "$PR_BODY_FILE"
if [ $? -eq 0 ]; then
echo "✅ ドラフトPRが正常に作成されました"
# PR URLを取得して表示
PR_URL=$(gh pr view --json url -q .url)
echo "🔗 PR URL: $PR_URL"
echo ""
echo "📋 次のステップ:"
echo "1. PRの内容を確認・編集"
echo "2. レビュアーを追加"
echo "3. 準備ができたらドラフト状態を解除"
echo "4. 必要に応じてラベルやマイルストーンを設定"
else
echo "❌ PR作成に失敗しました"
echo "💡 トラブルシューティング:"
echo "- GitHub CLIの認証状態を確認: gh auth status"
echo "- リポジトリの権限を確認"
echo "- ブランチが正しくpushされているか確認"
fi
```
## 重要なルール
- **必ずドラフト状態で作成**: コードレビューの準備ができるまでドラフト状態を維持
- **PRテンプレートをベースに使用**: `.github/PULL_REQUEST_TEMPLATE.md` が存在する場合は、その構造を基本として使用し、変更内容を自動で挿入
- **適切なpush**: `git push -u origin <branch_name>` のように `--set-upstream` を指定
- **意味のあるタイトル**: コミットメッセージや機能の概要を反映
## PRテンプレート活用の詳細
- **テンプレートがある場合**: テンプレートの構造を維持し、概要セクションに変更内容を自動挿入
- **テンプレートがない場合**: デフォルトの構造(概要、変更一覧、テスト計画、チェックリスト)を使用
- **多言語対応**: 英語・日本語の一般的なセクション名に対応Overview/概要、Summary/概要、Changed Files/変更されたファイル)
## 注意事項
- PRテンプレートの既存構造を尊重し、必要な項目は自動補完します
- コミットメッセージは意味のある内容にしてください
- 破壊的変更がある場合は説明に明記してください
- レビュアーの追加は手動で行ってください

306
commands/pr-fix.md Normal file
View File

@@ -0,0 +1,306 @@
# GitHub PR 自動修正コマンド
PRのレビューコメント(🚀リアクション付き)とCIエラーを自動的に修正します。
## 使用方法
```bash
/pr-fix [pr番号]
```
PR番号が指定されない場合は、現在のブランチのPRを使用します。
**重要**: 修正したいレビューコメントに🚀リアクションを追加してから実行してください。🚀リアクションがついたコメントのみが修正対象になります。
## 処理手順
1. PRとレビューコメント(🚀リアクション付き)を取得
2. CIの失敗状況を確認
3. レビューコメントの修正を適用
4. CIエラーを修正
5. テストとリンティングを実行して検証
6. コミットせずに変更内容の概要を表示
## 実装
### ステップ1: PR情報の取得
```bash
# PR番号の取得または指定
if [ -z "$1" ]; then
# 現在のブランチのPRを取得
CURRENT_BRANCH=$(git branch --show-current)
echo "🌿 現在のブランチ: $CURRENT_BRANCH"
PR_INFO=$(gh pr list --head "$CURRENT_BRANCH" --json number 2>/dev/null)
if [ -z "$PR_INFO" ] || [ "$PR_INFO" = "[]" ]; then
echo "❌ 現在のブランチにPRが見つかりません"
echo "💡 /pr-create でPRを作成するか、PR番号を指定してください: /pr-fix <PR番号>"
exit 1
fi
PR_NUMBER=$(echo "$PR_INFO" | jq -r '.[0].number')
else
PR_NUMBER=$1
fi
echo "📋 PR #$PR_NUMBER を修正します"
echo ""
```
### ステップ2: レビューコメント(🚀リアクション付き)の取得
```bash
echo "🚀 🚀リアクション付きレビューコメントを取得中..."
# PRのレビューコメントを取得
COMMENTS=$(gh api "repos/:owner/:repo/pulls/$PR_NUMBER/comments" 2>/dev/null || echo "")
if [ -z "$COMMENTS" ] || [ "$COMMENTS" = "[]" ]; then
echo " レビューコメントが見つかりません"
REVIEW_COMMENTS=""
else
# 🚀リアクション(rocket)がついたコメントのみを抽出
REVIEW_COMMENTS=$(echo "$COMMENTS" | jq -r '.[] | select(.reactions.rocket > 0) | {path: .path, line: .position, body: .body, id: .id} | @json')
if [ -z "$REVIEW_COMMENTS" ]; then
echo " 🚀リアクションがついたレビューコメントが見つかりません"
echo "💡 修正したいコメントに🚀リアクションを追加してから再実行してください"
else
COMMENT_COUNT=$(echo "$REVIEW_COMMENTS" | wc -l | tr -d ' ')
echo "📋 🚀リアクション付きコメント: ${COMMENT_COUNT}"
echo ""
echo "$REVIEW_COMMENTS" | jq -r '. | "- \(.path):\(.line) - \(.body)"'
echo ""
fi
fi
```
### ステップ3: CIエラーの確認
```bash
echo "🔍 CIエラーを確認中..."
# PRのチェック状態を取得
CHECK_RUNS=$(gh pr checks "$PR_NUMBER" 2>/dev/null || echo "")
if [ -n "$CHECK_RUNS" ]; then
FAILED_CHECKS=$(echo "$CHECK_RUNS" | grep -E "(fail|error|✗)" || echo "")
if [ -n "$FAILED_CHECKS" ]; then
echo "❌ CIエラーが見つかりました:"
echo "$FAILED_CHECKS"
echo ""
else
echo "✅ CIエラーはありません"
FAILED_CHECKS=""
fi
else
echo " CI情報を取得できませんでした"
FAILED_CHECKS=""
fi
# 修正対象が何もない場合は終了
if [ -z "$REVIEW_COMMENTS" ] && [ -z "$FAILED_CHECKS" ]; then
echo "✅ 修正対象が見つかりませんでした"
exit 0
fi
echo "🔧 修正を開始します..."
echo ""
```
### ステップ4: レビューコメントの修正適用
レビューコメントの種類に応じて適切な修正を実行:
1. **コードの提案**: 提案されたコード変更を直接適用
2. **スタイル/フォーマット**: リンターやフォーマッターを実行
3. **ロジックの問題**: 要求されたロジック変更を実装
4. **ドキュメント**: コメント、README、ドキュメントを更新
5. **テスト**: テストを追加または修正
6. **セキュリティ**: セキュリティ関連の修正を実施
```bash
if [ -n "$REVIEW_COMMENTS" ]; then
echo "📝 レビューコメントの修正を適用中..."
echo ""
echo "以下のレビューコメントを修正してください:"
echo "$REVIEW_COMMENTS" | jq -r '. | "\(.path):\(.line) - \(.body)"'
echo ""
echo "⚠️ 重要な制約:"
echo " - コードの品質を保ちながら修正すること"
echo " - 既存のコードスタイルに従うこと"
echo " - テストが通ることを確認すること"
echo ""
fi
```
### ステップ5: CIエラーの修正
CIエラーの種類に応じて自動修正を実行:
#### リンティングエラーの修正
```bash
if echo "$FAILED_CHECKS" | grep -qi "lint"; then
echo "📝 リンティングエラーを修正中..."
if [ -f "package.json" ]; then
echo "🔧 npm run lint --fix を実行中..."
npm run lint --fix 2>/dev/null || npm run lint:fix 2>/dev/null || echo "lintコマンドが見つかりません"
fi
if command -v ruff >/dev/null 2>&1; then
echo "🔧 ruff check --fix を実行中..."
ruff check --fix .
fi
if command -v golangci-lint >/dev/null 2>&1; then
echo "🔧 golangci-lint を実行中..."
golangci-lint run --fix
fi
echo "✅ リンティング修正完了"
echo ""
fi
```
#### 型エラーの修正
```bash
if echo "$FAILED_CHECKS" | grep -qi "type\|typescript"; then
echo "🏷️ 型エラーを分析中..."
if [ -f "tsconfig.json" ]; then
echo "🔧 TypeScript型チェックを実行中..."
npx tsc --noEmit 2>&1 | head -30
echo ""
echo "💡 上記の型エラーを修正してください"
echo ""
fi
fi
```
#### テスト失敗の修正
```bash
if echo "$FAILED_CHECKS" | grep -qi "test"; then
echo "🧪 テスト失敗を分析中..."
if [ -f "package.json" ]; then
echo "🔧 npm test を実行中..."
npm test 2>&1 | tail -30
elif [ -f "pytest.ini" ] || [ -f "pyproject.toml" ]; then
echo "🔧 pytest を実行中..."
python -m pytest -v --tb=short 2>&1 | tail -30
elif [ -f "go.mod" ]; then
echo "🔧 go test を実行中..."
go test ./... -v 2>&1 | tail -30
fi
echo ""
echo "💡 テスト失敗の詳細を確認して修正してください"
echo ""
fi
```
#### ビルドエラーの修正
```bash
if echo "$FAILED_CHECKS" | grep -qi "build"; then
echo "🏗️ ビルドエラーを修正中..."
if [ -f "package.json" ]; then
echo "📦 依存関係を更新中..."
npm install
echo "🔧 ビルドを試行中..."
npm run build 2>&1 | tail -30
fi
if [ -f "requirements.txt" ]; then
echo "📦 Python依存関係を更新中..."
pip install -r requirements.txt
fi
if [ -f "go.mod" ]; then
echo "📦 Go依存関係を更新中..."
go mod tidy
go build ./...
fi
echo ""
fi
```
### ステップ6: 修正の検証
```bash
echo "🧪 修正の検証中..."
echo ""
# リンティングチェック
echo "🔍 リンティングチェックを実行中..."
if [ -f "package.json" ]; then
npm run lint 2>/dev/null || echo "lintコマンドをスキップ"
fi
# テスト実行
echo "🧪 テストを実行中..."
if [ -f "package.json" ]; then
npm test 2>/dev/null && echo "✅ テスト成功" || echo "⚠️ テストで問題が残っています"
elif [ -f "pytest.ini" ] || [ -f "pyproject.toml" ]; then
python -m pytest 2>/dev/null && echo "✅ テスト成功" || echo "⚠️ テストで問題が残っています"
fi
echo ""
```
### ステップ7: 修正結果の表示
```bash
# 変更内容の確認
echo "📝 修正内容の確認:"
git status --porcelain
if [ -n "$(git status --porcelain)" ]; then
echo ""
echo "📋 修正されたファイル:"
git diff --name-only
echo ""
echo "📊 変更統計:"
git diff --stat
echo ""
echo "✅ 修正が適用されました!"
echo ""
echo "🔄 次のステップ:"
echo "1. 'git diff' で変更内容を詳細確認"
echo "2. 必要に応じて追加の修正を実施"
echo "3. /commit でコミット作成"
echo "4. /push-current でリモートにpush"
echo "5. 数分後に /ci-check で状態を確認"
else
echo ""
echo " 自動修正可能な変更が見つかりませんでした"
echo "💡 以下の対応が必要です:"
if [ -n "$REVIEW_COMMENTS" ]; then
echo " - レビューコメントの手動修正"
fi
if [ -n "$FAILED_CHECKS" ]; then
echo " - CIエラーの手動修正"
fi
fi
```
## 修正対象のまとめ
### レビューコメント修正
- 🚀リアクションがついたコメントのみを対象
- コードの提案を直接適用
- スタイル、ロジック、ドキュメント、テストの修正
### CIエラー修正
1. **リンティングエラー**: 自動修正ツールを実行
2. **型エラー**: TypeScript等の型チェックと分析
3. **テスト失敗**: テストを実行して失敗箇所を特定
4. **ビルドエラー**: 依存関係の更新とビルド実行
## エラーハンドリング
- PRが存在しない場合は適切なメッセージを表示
- GitHub CLIの権限エラー時は対処法を案内
- レビューコメントが不明確な場合はTODOコメントを追加
- 自動修正が不可能な場合は手動修正の必要性を通知
## 注意事項
- **🚀リアクション必須**: 修正したいコメントに🚀リアクションを追加してください
- すべてのエラーが自動修正できるわけではありません
- 複雑なロジックエラーは手動での修正が必要です
- 修正後は必ずローカルでテストを実行して検証してください
- コミットとプッシュは手動で実行してください

38
commands/pr-list.md Normal file
View File

@@ -0,0 +1,38 @@
# PR List
オープン中のPR一覧を表示するカスタムコマンド。
```bash
# GitHub CLIの確認
if ! command -v gh &> /dev/null; then
echo "❌ Error: GitHub CLI (gh) がインストールされていません"
echo "インストール方法: https://cli.github.com/"
exit 1
fi
echo "📋 オープン中のPR一覧:"
echo "=========================="
# オープン中のPRを取得して表示
PR_COUNT=$(gh pr list --state open --json number | jq length)
if [ "$PR_COUNT" -eq 0 ]; then
echo ""
echo "✨ 現在オープン中のPRはありません"
else
# jqクエリを一時ファイルに保存して実行
cat << 'EOF' > /tmp/pr-list-format.jq
.[] |
"🔹 #\(.number) \(.title)
📂 Branch: \(.headRefName)
👤 Author: \(.author.login)
📅 Created: \(.createdAt)
\(if .statusCheckRollup and (.statusCheckRollup | length) > 0 then "🔍 CI Status: \(.statusCheckRollup | group_by(.conclusion) | map(if .[0].conclusion == "SUCCESS" then "✅ 成功: \(length)" elif .[0].conclusion == "FAILURE" then "❌ 失敗: \(length)" elif .[0].conclusion == null then "🔄 実行中: \(length)" else "\(.[0].conclusion): \(length)" end) | join(", "))" else "🔍 CI Status: No checks" end)
🔗 URL: \(.url)
"
EOF
gh pr list --state open --json number,title,headRefName,author,createdAt,url,statusCheckRollup | jq -r -f /tmp/pr-list-format.jq
rm -f /tmp/pr-list-format.jq
fi
```

170
commands/pr-review.md Normal file
View File

@@ -0,0 +1,170 @@
# PRレビュー - 包括的なコードレビュー実行
指定されたPull Requestを詳細にレビューし、改善提案を行います。
## 使用方法
`/pr-review <PR番号またはURL>`
例:
- `/pr-review 123`
- `/pr-review https://github.com/owner/repo/pull/123`
## 実行手順
### 1. PR情報の取得と検証
- `gh pr view <PR番号> --json` でPR詳細情報を取得
- タイトル、説明、作成者、ステータスを確認
- ターゲットブランチとソースブランチの確認
- 認証エラー時はフォールバック処理を実行
### 2. 変更内容の分析
- `gh pr diff <PR番号>` で差分を取得
- 変更されたファイル一覧を取得 (`gh pr view --json files`)
- 追加・削除された行数の統計情報を収集
- コミット履歴の確認 (`gh pr view --json commits`)
### 3. コードレビューの実施
#### 3.1 自動チェック項目
- **セキュリティ(最重要・厚めにチェック)**
- **認証・認可**
- ハードコードされた認証情報API key, password, token等
- 認証トークンの安全な保管方法
- 認可チェックの実装(権限検証の欠落)
- セッション管理の安全性
- **インジェクション攻撃**
- SQLインジェクション脆弱性
- NoSQLインジェクション
- コマンドインジェクション
- XSSStored/Reflected/DOM-based
- LDAP/XMLインジェクション
- **入力検証とサニタイゼーション**
- ユーザー入力の検証不足
- ファイルアップロードの検証
- Content-Type検証
- サイズ制限の実装
- ホワイトリスト方式の採用
- **データ保護**
- 機密情報のログ出力
- 暗号化の適切な実装
- 安全でない乱数生成
- パスワードのハッシュ化bcrypt、Argon2等
- **API/ネットワークセキュリティ**
- CORS設定の安全性
- CSRF対策の実装
- Rate limiting の実装
- HTTPSの強制
- **依存関係のセキュリティ**
- 既知の脆弱性を持つライブラリ
- 最新版への更新の必要性
- **その他のセキュリティ**
- パストラバーサル脆弱性
- XXEXML External Entity攻撃
- サーバーサイドリクエストフォージェリSSRF
- 安全でないデシリアライゼーション
- **テストケース(重要・厚めにチェック)**
- **テストカバレッジ**
- 新規機能に対するテストの有無
- 既存機能への影響範囲のテスト
- エッジケースのカバー状況
- エラーケースのテスト
- **テストの種類と品質**
- 単体テストUnit Testの適切性
- 統合テストIntegration Testの必要性
- E2Eテストの必要性
- テストの可読性と保守性
- **テストケースの十分性**
- 正常系のテスト
- 異常系のテスト(バリデーションエラー、ネットワークエラー等)
- 境界値テスト
- 並行処理のテスト(該当する場合)
- **セキュリティテスト**
- 認証・認可のテスト
- 入力検証のテスト
- エラーハンドリングのテスト
- **モックとテストデータ**
- 外部依存のモック化
- テストデータの適切性
- テスト環境の分離
- **パフォーマンステスト**
- 負荷テストの必要性評価
- レスポンスタイムの検証
- **過剰なテストの検出**
- 実装の詳細に依存しすぎたテスト(脆弱なテスト)
- 重複したテストケース
- 価値の低いテスト(自明な処理のテスト)
- メンテナンスコストが高すぎるテスト
- 不要にモックが多すぎるテスト
- **コード品質**
- 命名規則の一貫性
- 重複コードの検出
- 複雑度の評価
- デッドコードの検出
- **パフォーマンス**
- N+1クエリの検出
- 非効率なループ処理
- 不要な再レンダリング(フロントエンド)
- メモリリークの可能性
- **保守性**
- 適切なコメントの有無
- エラーハンドリングの実装
- ログ出力の適切性
- ドキュメントの更新
#### 3.2 プロジェクト固有のチェック
- プロジェクトのコーディング規約への準拠
- 既存のアーキテクチャとの整合性
- 依存関係の適切な管理
### 4. レビュー結果のフォーマット
#### 4.1 サマリー
- 全体的な評価Approve/Request Changes/Comment
- 主要な問題点の要約
- 良い点の強調
#### 4.2 詳細フィードバック
各ファイルごとに:
- 問題点の指摘(行番号付き)
- 改善提案と具体的なコード例
- 参考となるドキュメントやベストプラクティスへのリンク
#### 4.3 アクションアイテム
- 必須の修正項目(ブロッカー)
- 推奨される改善項目
- 将来的な改善提案
### 5. GitHub上でのコメント投稿オプション
- `gh pr comment` を使用してレビューコメントを投稿
- 行単位のインラインコメント
- 全体的なレビューコメント
## エラーハンドリング
### GitHub CLI認証エラー
プライベートリポジトリで認証エラーが発生した場合:
1. エラーメッセージを表示
2. 手動でPRを確認するためのURLを提供
3. 認証の再設定方法を案内:
- `gh auth refresh -s repo,read:org`
- GITHUB_TOKEN環境変数の確認
### API制限
- レート制限に達した場合の待機処理
- 部分的な結果での続行オプション
## 設定オプション
- `--format`: 出力形式markdown/json/html
- `--severity`: レビューの厳密さstrict/normal/lenient
- `--focus`: 特定の観点に絞るsecurity/performance/style
- `--no-comment`: GitHubへのコメント投稿をスキップ
## 前提条件
- GitHub CLIがインストールされ認証済みであること
- 対象リポジトリへの読み取りアクセス権限
- PR番号またはURLが有効であること

64
commands/pr-zero.md Normal file
View File

@@ -0,0 +1,64 @@
# Git Full Workflow - ブランチ作成からPR作成まで
ブランチ作成、コミット分割、PR作成を一連で実行するワークフロー
## 実行手順
### 1. ブランチ作成
- ブランチ名は [Conventional Branch](https://conventional-branch.github.io/) に従う
- feature/[FeatureName]-[実装した機能名] の形式
- 例: `feature/admin-user-role-edit-invite-form`
- 現在の変更をstashしてから新しいブランチを作成
### 2. 変更内容の確認と分析
- `git status` で変更ファイルを確認
- `git diff` で変更内容を確認
- 論理的な単位で複数のコミットに分割する計画を立てる
### 3. コミット分割と作成
- 関連する変更をグループ化して段階的にコミット
- [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) に従う
- type(scope): subject の形式(例: feat(auth): add user login validation
- タイトルは50文字以内、本文は72文字程度で改行
- 動詞は原形を使用add, fix, updateなど
- コミットメッセージは小文字で始める
### 4. プッシュとPR作成
- `git push -u origin <branch_name>` でプッシュ
- GitHub CLI認証状態を確認
- プライベートリポジトリの場合、認証エラー時はフォールバック処理を実行
- PRテンプレートの確認
- 以下の順序で検索:
1. `.github/PULL_REQUEST_TEMPLATE.md`
2. `.github/pull_request_template.md`
3. `.github/PULL_REQUEST_TEMPLATE/*.md`
4. `find . -name "*PULL_REQUEST_TEMPLATE*" -o -name "*pull_request_template*"`
- テンプレートが存在する場合は、その構造をベースとして使用
- 概要セクション(## 概要/## Overview/## Summaryに変更内容を自動挿入
- 変更ファイル情報も適切なセクションに追加
- `gh pr create --draft` でドラフトPRを作成
- 認証エラーの場合、手動PR作成URLを提供
## パラメータ
- branch_name: 作成するブランチ名feature/で始まる)
- commit_strategy: auto自動分割または manual手動確認
## 注意事項
- 実装とテストが含まれる場合、typeはfeat/fixを優先
- PRはDraftで作成し、レビュー準備ができてからDraftを外す
- コミット分割は論理的な変更単位を意識する
- プライベートリポジトリでは認証スコープ不足時に自動フォールバック
- GitHub CLIエラー時は手動PR作成用のURLを提供する
- PRテンプレートがある場合は、既存の構造を尊重しつつ必要な情報を自動補完
- 多言語対応:英語・日本語の一般的なセクション名に対応
## エラーハンドリング
### GitHub CLI認証エラー
- プライベートリポジトリで "Could not resolve to a Repository" エラーが発生した場合
- 以下の手動PR作成URLを提供
`https://github.com/{owner}/{repo}/compare/{base}...{branch}`
- 必要に応じて認証の再設定を案内
### 認証スコープ不足
- GITHUB_TOKEN環境変数使用時は、十分なスコープ(repo, read:org)が必要
- 環境変数未設定の場合は `gh auth refresh -s repo,read:org` で再認証

38
commands/push-current.md Normal file
View File

@@ -0,0 +1,38 @@
# Git Push Current Branch
現在のブランチをリモートにpushするカスタムコマンド
```bash
# 現在のブランチ名を取得
CURRENT_BRANCH=$(git branch --show-current)
if [ -z "$CURRENT_BRANCH" ]; then
echo "Error: ブランチ名を取得できませんでした"
exit 1
fi
echo "現在のブランチ: $CURRENT_BRANCH"
# メインブランチのチェック
if [ "$CURRENT_BRANCH" = "main" ] || [ "$CURRENT_BRANCH" = "master" ]; then
echo "❌ Error: メインブランチ ($CURRENT_BRANCH) への直接pushは禁止されています"
echo "フィーチャーブランチを作成してください"
exit 1
fi
# リモートブランチの存在確認
if git ls-remote --heads origin "$CURRENT_BRANCH" | grep -q "$CURRENT_BRANCH"; then
echo "リモートブランチが存在します。pushを実行..."
git push origin "$CURRENT_BRANCH"
else
echo "リモートにブランチが存在しません。upstream設定付きでpushを実行..."
git push -u origin "$CURRENT_BRANCH"
fi
if [ $? -eq 0 ]; then
echo "✅ push完了: $CURRENT_BRANCH"
else
echo "❌ pushに失敗しました"
exit 1
fi
```

482
commands/review-diff.md Normal file
View File

@@ -0,0 +1,482 @@
# コード差分レビューコマンド
現在のコード差分を分析し、コーディング規約とベストプラクティスに従ったレビューを実施します。
## 使用方法
```bash
/review-diff [対象ファイル・ディレクトリ]
```
対象が指定されない場合は、すべての変更されたファイルをレビューします。
## 処理手順
1. 現在の変更差分を取得・分析
2. プロジェクトのコーディング規約を特定
3. 使用技術のベストプラクティスを適用
4. 問題点と改善提案を整理
5. 詳細なレビューレポートを生成
## 実装
### ステップ1: 変更差分の取得
```bash
# git statusで変更ファイルを確認
echo "📋 変更されたファイルを確認中..."
CHANGED_FILES=$(git status --porcelain)
if [ -z "$CHANGED_FILES" ]; then
echo " レビュー対象の変更がありません"
exit 0
fi
echo "📝 変更されたファイル:"
echo "$CHANGED_FILES"
echo ""
# 詳細差分を取得
echo "🔍 差分を分析中..."
DIFF_CONTENT=$(git diff --no-color)
STAGED_DIFF=$(git diff --cached --no-color)
if [ -n "$STAGED_DIFF" ]; then
echo "📦 ステージング済みの変更も含めて分析します"
DIFF_CONTENT="$DIFF_CONTENT\n\n=== STAGED CHANGES ===\n$STAGED_DIFF"
fi
```
### ステップ2: プロジェクト環境の分析
```bash
# プロジェクトの技術スタックを特定
echo "🔍 プロジェクト環境を分析中..."
PROJECT_TYPE=""
LANGUAGES=()
FRAMEWORKS=()
CONFIG_FILES=()
# 言語・フレームワークの検出
if [ -f "package.json" ]; then
PROJECT_TYPE="Node.js"
LANGUAGES+=("JavaScript" "TypeScript")
echo "📦 Node.js プロジェクトを検出"
# フレームワーク検出
if grep -q "react" package.json; then
FRAMEWORKS+=("React")
fi
if grep -q "vue" package.json; then
FRAMEWORKS+=("Vue.js")
fi
if grep -q "next" package.json; then
FRAMEWORKS+=("Next.js")
fi
if grep -q "express" package.json; then
FRAMEWORKS+=("Express")
fi
CONFIG_FILES+=("package.json" ".eslintrc*" ".prettierrc*" "tsconfig.json")
fi
if [ -f "requirements.txt" ] || [ -f "pyproject.toml" ] || [ -f "setup.py" ]; then
PROJECT_TYPE="Python"
LANGUAGES+=("Python")
echo "🐍 Python プロジェクトを検出"
if grep -q "django" requirements.txt 2>/dev/null; then
FRAMEWORKS+=("Django")
fi
if grep -q "flask" requirements.txt 2>/dev/null; then
FRAMEWORKS+=("Flask")
fi
if grep -q "fastapi" requirements.txt 2>/dev/null; then
FRAMEWORKS+=("FastAPI")
fi
CONFIG_FILES+=("requirements.txt" "pyproject.toml" ".flake8" "mypy.ini")
fi
if [ -f "go.mod" ]; then
PROJECT_TYPE="Go"
LANGUAGES+=("Go")
echo "🔷 Go プロジェクトを検出"
CONFIG_FILES+=("go.mod" "go.sum")
fi
if [ -f "Cargo.toml" ]; then
PROJECT_TYPE="Rust"
LANGUAGES+=("Rust")
echo "🦀 Rust プロジェクトを検出"
CONFIG_FILES+=("Cargo.toml" "Cargo.lock")
fi
# その他の設定ファイル
CONFIG_FILES+=(".gitignore" "README.md" ".editorconfig")
echo "🏗️ 検出された技術スタック:"
echo " 言語: ${LANGUAGES[*]}"
echo " フレームワーク: ${FRAMEWORKS[*]}"
```
### ステップ3: レビュー基準の設定
```bash
# レビュー基準を設定
echo "📐 レビュー基準を設定中..."
REVIEW_CRITERIA=()
# 共通基準
REVIEW_CRITERIA+=(
"コードの可読性と保守性"
"命名規則の一貫性"
"セキュリティベストプラクティス"
"パフォーマンス最適化"
"エラーハンドリング"
"テスタビリティ"
"ドキュメント整備"
)
# 言語固有の基準
for lang in "${LANGUAGES[@]}"; do
case $lang in
"JavaScript"|"TypeScript")
REVIEW_CRITERIA+=(
"ESLint/Prettier準拠"
"型安全性TypeScript"
"非同期処理のベストプラクティス"
"メモリリーク対策"
"バンドルサイズ最適化"
)
;;
"Python")
REVIEW_CRITERIA+=(
"PEP 8準拠"
"型ヒント使用"
"例外処理の適切性"
"パッケージ構造"
"docstring記述"
)
;;
"Go")
REVIEW_CRITERIA+=(
"Go Convention準拠"
"エラーハンドリング"
"Goroutineとチャネルの使用"
"メモリ効率"
"テストカバレッジ"
)
;;
"Rust")
REVIEW_CRITERIA+=(
"Rust Convention準拠"
"所有権とライフタイム"
"Result型でのエラーハンドリング"
"メモリ安全性"
"パフォーマンス"
)
;;
esac
done
echo "📋 適用されるレビュー基準:"
for criteria in "${REVIEW_CRITERIA[@]}"; do
echo " - $criteria"
done
```
### ステップ4: 自動チェックの実行
```bash
# 利用可能なリンター・チェッカーを実行
echo "🔧 自動チェックを実行中..."
LINT_RESULTS=()
# JavaScript/TypeScript
if command -v npm >/dev/null 2>&1 && [ -f "package.json" ]; then
echo "📝 ESLint チェック実行中..."
if npm run lint --silent 2>/dev/null; then
LINT_RESULTS+=("✅ ESLint: 問題なし")
else
LINT_RESULTS+=("❌ ESLint: 問題が検出されました")
fi
if command -v tsc >/dev/null 2>&1 && [ -f "tsconfig.json" ]; then
echo "🏷️ TypeScript型チェック実行中..."
if npx tsc --noEmit --skipLibCheck 2>/dev/null; then
LINT_RESULTS+=("✅ TypeScript: 型エラーなし")
else
LINT_RESULTS+=("❌ TypeScript: 型エラーが検出されました")
fi
fi
fi
# Python
if command -v ruff >/dev/null 2>&1; then
echo "🐍 Ruff チェック実行中..."
if ruff check . --quiet 2>/dev/null; then
LINT_RESULTS+=("✅ Ruff: 問題なし")
else
LINT_RESULTS+=("❌ Ruff: 問題が検出されました")
fi
fi
if command -v mypy >/dev/null 2>&1; then
echo "🏷️ MyPy型チェック実行中..."
if mypy . --ignore-missing-imports --quiet 2>/dev/null; then
LINT_RESULTS+=("✅ MyPy: 型エラーなし")
else
LINT_RESULTS+=("❌ MyPy: 型エラーが検出されました")
fi
fi
# Go
if command -v golangci-lint >/dev/null 2>&1 && [ -f "go.mod" ]; then
echo "🔷 golangci-lint チェック実行中..."
if golangci-lint run --quiet 2>/dev/null; then
LINT_RESULTS+=("✅ golangci-lint: 問題なし")
else
LINT_RESULTS+=("❌ golangci-lint: 問題が検出されました")
fi
fi
# Rust
if command -v cargo >/dev/null 2>&1 && [ -f "Cargo.toml" ]; then
echo "🦀 Cargo clippy チェック実行中..."
if cargo clippy --quiet -- -D warnings 2>/dev/null; then
LINT_RESULTS+=("✅ Clippy: 問題なし")
else
LINT_RESULTS+=("❌ Clippy: 問題が検出されました")
fi
fi
echo "🔍 自動チェック結果:"
for result in "${LINT_RESULTS[@]}"; do
echo " $result"
done
```
### ステップ5: レビューレポート生成
```bash
# レビューレポートを生成
echo ""
echo "📊 コード差分レビューレポート"
echo "=================================="
echo ""
echo "📅 レビュー実施日時: $(date '+%Y年%m月%d日 %H:%M:%S')"
echo "🏗️ プロジェクトタイプ: $PROJECT_TYPE"
echo "💻 検出言語: ${LANGUAGES[*]}"
echo "🚀 使用フレームワーク: ${FRAMEWORKS[*]}"
echo ""
echo "## 📋 変更ファイル一覧"
git status --porcelain | while read -r line; do
status=${line:0:2}
file=${line:3}
case $status in
"M ") echo " 📝 変更: $file" ;;
"A ") echo " 追加: $file" ;;
"D ") echo " ❌ 削除: $file" ;;
"R ") echo " 🔄 リネーム: $file" ;;
"??") echo " ❓ 未追跡: $file" ;;
*) echo " 📄 $status: $file" ;;
esac
done
echo ""
echo "## 🔧 自動チェック結果"
for result in "${LINT_RESULTS[@]}"; do
echo " $result"
done
echo ""
echo "## 📐 レビューポイント"
echo ""
echo "### ✅ 良い点"
echo "- Conventional Commits形式でのコミットメッセージ作成"
echo "- 適切なファイル構造とディレクトリ組織"
echo "- 設定ファイルの適切な管理"
echo ""
echo "### 🔍 改善提案"
echo ""
# ファイル別の具体的な改善提案
git diff --name-only | while read -r file; do
echo "#### 📄 $file"
case $file in
*.js|*.ts|*.jsx|*.tsx)
echo "- **JavaScript/TypeScript ベストプラクティス**"
echo " - console.log の削除を確認"
echo " - 未使用インポートの削除"
echo " - 適切な型定義の使用"
echo " - エラーハンドリングの実装"
;;
*.py)
echo "- **Python ベストプラクティス**"
echo " - PEP 8準拠の確認"
echo " - 型ヒントの追加"
echo " - docstringの記述"
echo " - 例外処理の適切な実装"
;;
*.go)
echo "- **Go ベストプラクティス**"
echo " - エラーハンドリングの確認"
echo " - 未使用変数の削除"
echo " - 適切なパッケージ構造"
echo " - テストの追加"
;;
*.rs)
echo "- **Rust ベストプラクティス**"
echo " - 所有権とライフタイムの確認"
echo " - Result型の適切な使用"
echo " - パフォーマンス最適化"
echo " - 安全性の確認"
;;
*.md)
echo "- **Markdown ドキュメント**"
echo " - リンクの有効性確認"
echo " - 見出し構造の整理"
echo " - コードブロックの言語指定"
echo " - 誤字脱字の確認"
;;
*.json)
echo "- **JSON設定ファイル**"
echo " - フォーマットの統一"
echo " - 不要なプロパティの削除"
echo " - セキュリティ設定の確認"
;;
*)
echo "- **一般的な改善点**"
echo " - ファイル形式の適切性"
echo " - 文字エンコーディングの確認"
echo " - 改行コードの統一"
;;
esac
echo ""
done
echo "### 🚀 次のステップ"
echo "1. 自動チェックで検出された問題の修正"
echo "2. 改善提案の検討・実装"
echo "3. テストの実行・追加"
echo "4. ドキュメントの更新"
echo "5. コードレビューの依頼"
echo ""
echo "## 📈 品質メトリクス"
echo ""
TOTAL_FILES=$(git diff --name-only | wc -l)
ADDED_LINES=$(git diff --numstat | awk '{add+=$1} END {print add+0}')
DELETED_LINES=$(git diff --numstat | awk '{del+=$2} END {print del+0}')
echo "📊 変更統計:"
echo " - 変更ファイル数: $TOTAL_FILES"
echo " - 追加行数: +$ADDED_LINES"
echo " - 削除行数: -$DELETED_LINES"
echo " - 正味変更: $((ADDED_LINES - DELETED_LINES))"
echo ""
echo "🎯 レビュー完了!改善提案を参考にコードの品質向上を図ってください。"
```
## レビュー対象
### **セキュリティ(最重要・厚めにチェック)**
- **認証・認可**
- ハードコードされた認証情報API key, password, token等
- 認証トークンの安全な保管方法
- 認可チェックの実装(権限検証の欠落)
- セッション管理の安全性
- **インジェクション攻撃**
- SQLインジェクション脆弱性
- NoSQLインジェクション
- コマンドインジェクション
- XSSStored/Reflected/DOM-based
- LDAP/XMLインジェクション
- **入力検証とサニタイゼーション**
- ユーザー入力の検証不足
- ファイルアップロードの検証
- Content-Type検証
- サイズ制限の実装
- ホワイトリスト方式の採用
- **データ保護**
- 機密情報のログ出力
- 暗号化の適切な実装
- 安全でない乱数生成
- パスワードのハッシュ化bcrypt、Argon2等
- **API/ネットワークセキュリティ**
- CORS設定の安全性
- CSRF対策の実装
- Rate limiting の実装
- HTTPSの強制
- **依存関係のセキュリティ**
- 既知の脆弱性を持つライブラリ
- 最新版への更新の必要性
- **その他のセキュリティ**
- パストラバーサル脆弱性
- XXEXML External Entity攻撃
- サーバーサイドリクエストフォージェリSSRF
- 安全でないデシリアライゼーション
### **テストケース(重要・厚めにチェック)**
- **テストカバレッジ**
- 新規機能に対するテストの有無
- 既存機能への影響範囲のテスト
- エッジケースのカバー状況
- エラーケースのテスト
- **テストの種類と品質**
- 単体テストUnit Testの適切性
- 統合テストIntegration Testの必要性
- E2Eテストの必要性
- テストの可読性と保守性
- **テストケースの十分性**
- 正常系のテスト
- 異常系のテスト(バリデーションエラー、ネットワークエラー等)
- 境界値テスト
- 並行処理のテスト(該当する場合)
- **セキュリティテスト**
- 認証・認可のテスト
- 入力検証のテスト
- エラーハンドリングのテスト
- **モックとテストデータ**
- 外部依存のモック化
- テストデータの適切性
- テスト環境の分離
- **パフォーマンステスト**
- 負荷テストの必要性評価
- レスポンスタイムの検証
- **過剰なテストの検出**
- 実装の詳細に依存しすぎたテスト(脆弱なテスト)
- 重複したテストケース
- 価値の低いテスト(自明な処理のテスト)
- メンテナンスコストが高すぎるテスト
- 不要にモックが多すぎるテスト
### **コード品質**
- 可読性、保守性、パフォーマンス
- 命名規則の一貫性
- 重複コードの検出
- 複雑度の評価
- デッドコードの検出
### **ベストプラクティス**
- 言語・フレームワーク固有の推奨事項
- 既存のアーキテクチャとの整合性
- 適切なエラーハンドリング
### **ドキュメント**
- README、コメント、型定義
- API仕様の更新
- 変更履歴の記録
## 技術スタック別対応
- **Node.js**: ESLint、Prettier、TypeScript
- **Python**: Ruff、MyPy、PEP 8
- **Go**: golangci-lint、Go Convention
- **Rust**: Clippy、Rust Convention
## 注意事項
- 自動チェックツールが利用可能な場合のみ実行
- プロジェクト固有のルールがある場合は設定ファイルを参照
- レビュー結果は参考として活用し、最終判断は開発者が行う
- セキュリティに関わる問題は特に注意深く確認

163
commands/review-fix.md Normal file
View File

@@ -0,0 +1,163 @@
# GitHub PR レビューコメント修正コマンド
PRのレビューコメントを自動的にチェックして、要求された修正を適用します。
## 使用方法
```bash
/review-fix [pr番号]
```
PR番号が指定されない場合は、現在のブランチのPRを使用します。
**重要**: 修正したいレビューコメントに👍リアクションを追加してから実行してください。👍リアクションがついたコメントのみが修正対象になります。
## 処理手順
1. GitHub CLIを使ってPRとレビューコメントを取得
2. 各レビューコメントを分析して実行可能なフィードバックを特定
3. 可能な限り要求された変更を自動適用
4. テストとリンティングを実行して修正を検証
5. コミットせずに変更内容の概要を表示
## 実装
PRの情報とレビューコメントの取得から開始します。
### ステップ1: PR情報の取得
```bash
# GitHub CLIの認証とスコープを最初にチェック
echo "🔍 GitHub CLIの設定を確認中..."
gh auth status
# PR番号が指定されていない場合は現在のブランチのPRを取得フォールバック処理付き
PR_INFO=$(gh pr view --json number,reviews,url 2>/dev/null || echo "")
if [ -z "$PR_INFO" ]; then
echo "❌ PR情報を取得できません。考えられる原因"
echo " - 現在のブランチにPRが存在しない"
echo " - GitHub CLIに追加のスコープが必要 (read:org, read:discussion)"
echo " - 認証の問題"
echo ""
echo "💡 GitHub CLIのスコープを修正するには"
echo " 1. https://github.com/settings/tokens にアクセス"
echo " 2. トークンに'read:org'と'read:discussion'スコープを追加"
echo " 3. 実行: gh auth login --with-token < your_token_file"
echo ""
echo "🔄 代替方法: PR番号を手動で指定 /review-fix <pr番号>"
exit 1
fi
# 後続のコマンドで使用するためにPR番号を抽出
PR_NUMBER=$(echo "$PR_INFO" | jq -r '.number')
echo "📋 PR #$PR_NUMBER を発見"
```
### ステップ2: レビューコメントの取得
```bash
# 包括的なエラーハンドリングでレビューコメントを取得
echo "📥 PR #$PR_NUMBER のレビューコメントを取得中..."
# レビューデータを取得する複数の方法を試行
REVIEWS=$(gh pr view $PR_NUMBER --json reviews 2>/dev/null || echo "")
COMMENTS=$(gh api "repos/:owner/:repo/pulls/$PR_NUMBER/comments" 2>/dev/null || echo "")
if [ -z "$REVIEWS" ] && [ -z "$COMMENTS" ]; then
echo "❌ レビューコメントを取得できません。GitHub CLIの権限を確認してください。"
echo "💡 必要なスコープ: repo, read:org, read:discussion"
exit 1
fi
# レビューサマリーを解析して表示
echo "📊 レビューサマリー:"
if [ -n "$REVIEWS" ]; then
echo "$REVIEWS" | jq -r '.reviews[] | "- \(.state) by \(.user.login): \(.body // "コメントなし")"'
fi
if [ -n "$COMMENTS" ]; then
echo "💬 行コメント:"
echo "$COMMENTS" | jq -r '.[] | "- \(.path):\(.line) - \(.body)"'
fi
```
### ステップ3: 修正対象コメントの特定
```bash
# 👍リアクションがついたコメントを修正対象として特定
echo "🔍 修正対象のレビューコメントを特定中..."
# 👍リアクションがついているコメントのみを抽出
TARGET_COMMENTS=$(echo "$COMMENTS" | jq -r '.[] | select(.reactions."+1" > 0) | {path: .path, line: .line, body: .body}')
if [ -z "$TARGET_COMMENTS" ] || [ "$TARGET_COMMENTS" = "null" ]; then
echo " 👍リアクションがついたレビューコメントが見つかりません"
echo "💡 修正したいコメントに👍リアクションを追加してから再実行してください"
exit 0
fi
echo "📋 修正対象のコメント:"
echo "$TARGET_COMMENTS" | jq -r '"- \(.path):\(.line) - \(.body)"'
```
### ステップ4: コメントの解析と分類
👍リアクションがついた各レビューコメントについて:
1. **コードの提案**: 提案されたコード変更を直接適用
2. **スタイル/フォーマット**: 適切なリンターやフォーマッターを実行
3. **ロジックの問題**: 要求されたロジック変更を分析して実装
4. **ドキュメント**: 要求に応じてコメント、README、ドキュメントを更新
5. **テスト**: 提案に従ってテストを追加または修正
6. **セキュリティ懸念**: セキュリティ関連のフィードバックに対処
### ステップ5: 修正の体系的適用
- レビューコメントのファイルパスと行番号を使用して、必要な変更箇所を正確に特定
- コードの提案については、提案されたdiffを直接適用
- より幅広いフィードバックについては、包括的な修正を実装
- 各修正が既存の機能を破損しないことを検証
### ステップ6: 変更の検証
```bash
# 修正を検証するためにテストを実行(利用可能な場合)
echo "🧪 修正を検証するためにテストを実行中..."
npm test || python -m pytest || go test || cargo test || echo "テストコマンドが見つかりません"
# コードスタイルをチェックするためにリンティングを実行
echo "🔍 リンティングチェックを実行中..."
npm run lint || ruff check || golangci-lint run || echo "リントコマンドが見つかりません"
# 行われた変更を表示するためにgit statusを表示
echo "📝 行われた変更の概要:"
git status --porcelain
echo ""
echo "📋 詳細diff"
git diff --stat
echo ""
echo "✅ レビュー修正が正常に適用されました!"
echo "💡 準備ができたら /commit-create を使用してこれらの変更をコミットしてください"
```
### ステップ7: サマリーレポート
```bash
# 適用された修正のサマリーを生成
echo "🤖 レビュー修正サマリー:"
echo "- PRレビューコメントの問題を修正"
echo "- 可能な限りコードの提案を適用"
echo "- スタイル/フォーマットの問題を解決"
echo "- 要求に応じてドキュメントを更新"
echo ""
echo "📊 変更されたファイル数: $(git diff --name-only | wc -l)"
echo "📈 変更された行数: +$(git diff --numstat | awk '{add+=$1} END {print add}') -$(git diff --numstat | awk '{del+=$2} END {print del}')"
echo ""
echo "🔄 次のステップ:"
echo "1. 'git diff' で変更内容を確認"
echo "2. 必要に応じて追加のテストを実行"
echo "3. 満足したら /commit-create を使用してコミット"
```
## エラーハンドリング
- レビューコメントが不明確な場合は、手動レビュー用のTODOコメントを表示
- 自動修正が不可能な場合は、コード内にTODOコメントを作成
- 修正後にテストが失敗した場合は、失敗詳細を表示してガイダンスを求める
- マージコンフリクトを適切に処理し、発見されたコンフリクトを報告
## 注意事項
- **👍リアクション必須**: 修正したいコメントに👍リアクションを追加してください
- 明確に要求され、安全な変更のみを適用
- 複雑なロジック変更については、保守的に実装し確認を求める
- 既存のコードスタイルとパターンを保持
- 修正を検証するために必ずテストを実行するが、自動的にはコミットしない
- レビュー後に変更をコミットするには /commit-create コマンドを使用

433
commands/test-create.md Normal file
View File

@@ -0,0 +1,433 @@
# テスト自動生成コマンド
現在の差分から変更されたファイルを検出し、既存のテスト実装パターンに基づいてテストを自動生成します。
## 使用方法
```bash
/test-create
```
## 処理手順
1. `git diff`で変更されたファイルを検出
2. 各ファイルの言語・フレームワークを識別
3. 既存のテストファイルからパターンを学習
4. 新規または更新されたテストファイルを生成
5. 生成されたテストの概要を表示
## 実装
### ステップ1: 変更ファイルの検出と分析
```bash
echo "🔍 変更されたファイルを検出中..."
# ステージングされた変更とステージングされていない変更の両方を取得
STAGED_FILES=$(git diff --cached --name-only)
UNSTAGED_FILES=$(git diff --name-only)
ALL_CHANGED_FILES=$(echo -e "$STAGED_FILES\n$UNSTAGED_FILES" | sort -u | grep -v "^$")
if [ -z "$ALL_CHANGED_FILES" ]; then
echo "❌ 変更されたファイルが見つかりません"
echo "💡 ファイルを変更してから再度実行してください"
exit 1
fi
echo "📝 変更されたファイル:"
echo "$ALL_CHANGED_FILES" | while read -r file; do
echo " - $file"
done
echo ""
```
### ステップ2: 各ファイルに対するテスト生成
変更されたファイルごとに:
1. ファイルの拡張子から言語を識別
2. 既存のテストパターンを検索
3. 適切なテストファイルを生成または更新
#### TypeScript/JavaScript ファイル
```bash
# TypeScript/JavaScript ファイルの処理
echo "$ALL_CHANGED_FILES" | grep -E "\.(ts|tsx|js|jsx)$" | while read -r file; do
if [ -z "$file" ]; then continue; fi
echo "📄 処理中: $file"
# テストファイル名を決定
TEST_FILE=""
if [[ "$file" == *.tsx ]]; then
TEST_FILE="${file%.tsx}.test.tsx"
elif [[ "$file" == *.ts ]]; then
TEST_FILE="${file%.ts}.test.ts"
elif [[ "$file" == *.jsx ]]; then
TEST_FILE="${file%.jsx}.test.jsx"
elif [[ "$file" == *.js ]]; then
TEST_FILE="${file%.js}.test.js"
fi
# __tests__ ディレクトリパターンをチェック
DIR=$(dirname "$file")
BASENAME=$(basename "$file")
if [ -d "$DIR/__tests__" ]; then
TEST_FILE="$DIR/__tests__/$BASENAME"
TEST_FILE="${TEST_FILE%.*}.test.${file##*.}"
fi
echo " → テストファイル: $TEST_FILE"
# 既存のテストパターンを検索
EXISTING_TEST_PATTERN=""
if [ -f "$TEST_FILE" ]; then
echo " ✓ 既存のテストファイルを更新"
else
# 同じプロジェクトの他のテストファイルからパターンを学習
SAMPLE_TEST=$(find "$(dirname "$file")" -name "*.test.*" -o -name "*.spec.*" | head -1)
if [ -n "$SAMPLE_TEST" ]; then
echo " 📚 テストパターンを学習: $SAMPLE_TEST"
fi
echo " ✓ 新規テストファイルを生成"
fi
done
```
#### Python ファイル
```bash
# Python ファイルの処理
echo "$ALL_CHANGED_FILES" | grep -E "\.py$" | while read -r file; do
if [ -z "$file" ]; then continue; fi
echo "📄 処理中: $file"
# テストファイル名を決定
TEST_FILE=""
BASENAME=$(basename "$file" .py)
DIR=$(dirname "$file")
# pytest規則に従う
if [[ "$file" == test_* ]] || [[ "$file" == *_test.py ]]; then
echo " スキップ: 既にテストファイルです"
continue
fi
# tests/ ディレクトリが存在するかチェック
if [ -d "$DIR/tests" ]; then
TEST_FILE="$DIR/tests/test_$BASENAME.py"
elif [ -d "tests" ]; then
# プロジェクトルートのtestsディレクトリ
TEST_FILE="tests/test_$BASENAME.py"
else
TEST_FILE="${DIR}/test_${BASENAME}.py"
fi
echo " → テストファイル: $TEST_FILE"
# 既存のテストパターンを検索
if [ -f "$TEST_FILE" ]; then
echo " ✓ 既存のテストファイルを更新"
else
# pytestパターンを検索
SAMPLE_TEST=$(find . -name "test_*.py" -o -name "*_test.py" | head -1)
if [ -n "$SAMPLE_TEST" ]; then
echo " 📚 テストパターンを学習: $SAMPLE_TEST"
fi
echo " ✓ 新規テストファイルを生成"
fi
done
```
#### Go ファイル
```bash
# Go ファイルの処理
echo "$ALL_CHANGED_FILES" | grep -E "\.go$" | grep -v "_test\.go$" | while read -r file; do
if [ -z "$file" ]; then continue; fi
echo "📄 処理中: $file"
# テストファイル名を決定
TEST_FILE="${file%.go}_test.go"
echo " → テストファイル: $TEST_FILE"
if [ -f "$TEST_FILE" ]; then
echo " ✓ 既存のテストファイルを更新"
else
echo " ✓ 新規テストファイルを生成"
fi
done
```
### ステップ3: テスト生成の実行
実際のテスト生成は、各言語・フレームワークに応じて以下を実行:
1. **関数・クラスの抽出**: 変更されたファイルから公開関数・クラスを抽出
2. **テストケースの生成**:
- 正常系テスト
- 異常系テスト
- エッジケーステスト
3. **既存テストとの統合**: 既存のテストがある場合は重複を避けて追加
```bash
echo ""
echo "🧪 テスト生成プロセス:"
echo ""
# 実際にテストファイルを生成する関数を定義
generate_js_test() {
local source_file="$1"
local test_file="$2"
local basename=$(basename "$source_file" | sed 's/\.[^.]*$//')
# テストファイルの内容を生成
cat > "$test_file" << EOF
import { describe, it, expect } from '@jest/globals';
import { $basename } from './$basename';
describe('$basename', () => {
it('should be defined', () => {
expect($basename).toBeDefined();
});
// TODO: 実際のテストケースを実装してください
// 以下は例です:
// it('should return expected result', () => {
// const result = $basename();
// expect(result).toBe(expectedValue);
// });
});
EOF
}
generate_python_test() {
local source_file="$1"
local test_file="$2"
local basename=$(basename "$source_file" .py)
local module_path=$(echo "$source_file" | sed 's/\//_/g' | sed 's/\.py$//')
# テストディレクトリがない場合は作成
mkdir -p "$(dirname "$test_file")"
cat > "$test_file" << EOF
import pytest
from $basename import *
class Test$(echo $basename | sed 's/^./\U&/')():
"""$basename モジュールのテストクラス"""
def test_module_import(self):
"""モジュールがインポートできることをテスト"""
# TODO: 実際のテストケースを実装してください
assert True
# TODO: 以下のようなテストメソッドを追加してください:
# def test_function_name(self):
# """function_name のテスト"""
# result = function_name()
# assert result == expected_value
EOF
}
generate_go_test() {
local source_file="$1"
local test_file="$2"
local package_name=$(head -1 "$source_file" | awk '{print $2}')
cat > "$test_file" << EOF
package $package_name
import (
"testing"
)
func TestPackage(t *testing.T) {
// TODO: 実際のテストケースを実装してください
// 以下は例です:
// func TestFunctionName(t *testing.T) {
// result := FunctionName()
// expected := "expected_value"
// if result != expected {
// t.Errorf("FunctionName() = %v, want %v", result, expected)
// }
// }
}
EOF
}
# 変更されたファイルに対してテストを生成
echo "$ALL_CHANGED_FILES" | while read -r file; do
if [ -z "$file" ] || [ ! -f "$file" ]; then continue; fi
# ファイルタイプを判定
EXT="${file##*.}"
case "$EXT" in
ts|tsx|js|jsx)
# テストファイル名を決定
TEST_FILE="${file%.*}.test.${EXT}"
if [[ "$file" == *".tsx" ]] || [[ "$file" == *".jsx" ]]; then
# React コンポーネントの場合は __tests__ ディレクトリも考慮
DIR=$(dirname "$file")
if [ -d "$DIR/__tests__" ]; then
BASENAME=$(basename "$file")
TEST_FILE="$DIR/__tests__/${BASENAME%.*}.test.${EXT}"
fi
fi
if [ ! -f "$TEST_FILE" ]; then
echo "🔧 JavaScript/TypeScriptテストを生成: $file$TEST_FILE"
generate_js_test "$file" "$TEST_FILE"
else
echo "⚠️ テストファイル既存: $TEST_FILE (スキップ)"
fi
;;
py)
if [[ "$file" != test_* ]] && [[ "$file" != *_test.py ]]; then
BASENAME=$(basename "$file" .py)
DIR=$(dirname "$file")
# テストファイル名を決定
if [ -d "$DIR/tests" ]; then
TEST_FILE="$DIR/tests/test_$BASENAME.py"
elif [ -d "tests" ]; then
TEST_FILE="tests/test_$BASENAME.py"
else
TEST_FILE="${DIR}/test_${BASENAME}.py"
fi
if [ ! -f "$TEST_FILE" ]; then
echo "🔧 Pythonテストを生成: $file$TEST_FILE"
generate_python_test "$file" "$TEST_FILE"
else
echo "⚠️ テストファイル既存: $TEST_FILE (スキップ)"
fi
fi
;;
go)
if [[ "$file" != *_test.go ]]; then
TEST_FILE="${file%.go}_test.go"
if [ ! -f "$TEST_FILE" ]; then
echo "🔧 Goテストを生成: $file$TEST_FILE"
generate_go_test "$file" "$TEST_FILE"
else
echo "⚠️ テストファイル既存: $TEST_FILE (スキップ)"
fi
fi
;;
*)
echo "⚠️ サポートされていないファイルタイプ: $file"
;;
esac
done
```
### ステップ4: 生成結果の表示
```bash
echo ""
echo "📊 テスト生成結果:"
echo ""
# 生成されたテストファイルを表示
NEW_TEST_FILES=$(git status --porcelain | grep "^??" | grep -E "\.(test|spec)\." | awk '{print $2}')
MODIFIED_TEST_FILES=$(git status --porcelain | grep "^ M" | grep -E "\.(test|spec)\." | awk '{print $2}')
if [ -n "$NEW_TEST_FILES" ]; then
echo "✨ 新規作成されたテストファイル:"
echo "$NEW_TEST_FILES" | while read -r file; do
echo " - $file"
done
fi
if [ -n "$MODIFIED_TEST_FILES" ]; then
echo "📝 更新されたテストファイル:"
echo "$MODIFIED_TEST_FILES" | while read -r file; do
echo " - $file"
done
fi
echo ""
echo "✅ テスト生成が完了しました!"
echo ""
echo "🔄 次のステップ:"
echo "1. 生成されたテストを確認: git diff"
echo "2. テストを実行: npm test / pytest / go test など"
echo "3. 必要に応じてテストを調整"
echo "4. テストが成功したら: /commit でコミット"
```
## 注意事項
- 生成されたテストは必ず手動で確認してください
- 既存のテストパターンがない場合は、一般的なパターンを使用します
- プライベート関数のテストは生成されません
- モックやスタブが必要な場合は手動で追加してください
## サポートされる言語とフレームワーク
### JavaScript/TypeScript
- Jest
- Mocha
- Vitest
- React Testing Library
### Python
- pytest
- unittest
- nose2
### Go
- 標準のtestingパッケージ
- testify
## 高度な使用方法
### 特定ファイルのみ対象
特定のファイルに対してのみテストを生成したい場合は、事前に変更をステージングしてください:
```bash
git add path/to/specific/file.ts
/test-create
```
これにより、ステージングされたファイルに対してのみテストが生成されます。
### インテリジェントなテスト生成
Claude Codeを使ってより高度なテストを生成することも可能です。実装の詳細に基づいたテストを生成したい場合は、以下のような拡張版を使用してください
```bash
# Claude Codeを使った高度なテスト生成
generate_intelligent_test() {
local source_file="$1"
local test_file="$2"
echo "🤖 Claude Codeを使って高度なテストを生成中: $source_file"
# ファイルの内容を読み取って、Claude Codeにテスト生成を依頼
cat > /tmp/test_generation_prompt.txt << EOF
以下のファイルの内容に基づいて、包括的なテストコードを生成してください。
ファイル: $source_file
EOF
cat "$source_file" >> /tmp/test_generation_prompt.txt
cat >> /tmp/test_generation_prompt.txt << EOF
要件:
1. すべての公開関数/メソッドをテストする
2. 正常系、異常系、エッジケースを含む
3. 適切なモックやスタブを使用する
4. テストの可読性を重視する
5. コメントは日本語で記述する
テストフレームワークは既存のプロジェクト設定に合わせて選択してください。
EOF
# Note: 実際の実装では、Claude Code APIを呼び出して
# テストコードを生成することができます
echo "💡 手動でテストコードをレビューして完成させてください"
}
```