```bash
Generates GitHub pull request drafts from current branch changes and pushes them.
/plugin marketplace add aglabo/claude-idd-framework/plugin install claude-idd-framework@claude-idd-framework-marketplace# Main command (generate draft)
/idd-pr [options]
# Subcommands
/idd-pr <subcommand> [options]
--output=<filename>: カスタムファイル名 (default: pr_current_draft.md)new: pr-generator エージェントで PR ドラフト生成 (デフォルト)view: 現在の PR ドラフト表示edit: PR ドラフト編集review: PR ドラフト詳細分析push: GitHub に PR 作成# PRドラフト生成(tempファイルに自動保存)
/idd-pr
/idd-pr new
# カスタムファイル名で生成
/idd-pr new --output=feature-123.md
# サブコマンドで詳細操作
/idd-pr view # ドラフト確認
/idd-pr edit # ドラフト編集
/idd-pr review # 詳細分析
/idd-pr push # GitHub にPR作成
<!-- markdownlint-disable no-duplicate-heading -->
このコマンドでは、Claude が以下の処理を実行:
config セクションから設定を取得{git_root}/{temp_dir}/{draft_file} でドラフトファイルパスを構築#!/bin/bash
# Load helper libraries
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIBS_DIR="$SCRIPT_DIR/_libs"
. "$LIBS_DIR/idd-session.lib.sh"
# Setup
REPO_ROOT=$(git rev-parse --show-toplevel)
PR_DIR="$REPO_ROOT/temp/idd/pr"
OUTPUT_FILE="${1:-pr_current_draft.md}" # --output=XXX から解析
DRAFT_PATH="$PR_DIR/$OUTPUT_FILE"
mkdir -p "$PR_DIR"
# Parse --output option if provided
for arg in "$@"; do
if [[ "$arg" =~ ^--output=(.+)$ ]]; then
OUTPUT_FILE="${BASH_REMATCH[1]}"
DRAFT_PATH="$PR_DIR/$OUTPUT_FILE"
fi
done
# Save the output filename for later use
_save_last_file "$PR_DIR" "$OUTPUT_FILE"
echo "🚀 Launching pr-generator agent..."
echo "📝 Output file: $DRAFT_PATH"
echo ""
echo "📊 Agent will analyze:"
echo " - Current branch commits"
echo " - File changes"
echo " - Related issues"
echo " - PR template structure"
echo ""
echo "⏳ Please wait for pr-generator agent to complete..."
# Note: Claude will invoke pr-generator agent via Task tool
# Agent prompt: "Generate PR draft and save to: $DRAFT_PATH"
#!/bin/bash
# Load helper libraries
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIBS_DIR="$SCRIPT_DIR/_libs"
. "$LIBS_DIR/idd-session.lib.sh"
REPO_ROOT=$(git rev-parse --show-toplevel)
PR_DIR="$REPO_ROOT/temp/idd/pr"
OUTPUT_FILE=$(_load_last_file "$PR_DIR" "pr_current_draft.md")
DRAFT_FILE="$PR_DIR/$OUTPUT_FILE"
PAGER="${PAGER:-less}"
if [[ -f "$DRAFT_FILE" ]]; then
echo "📄 Current PR Draft:"
echo "=================================================="
$PAGER "$DRAFT_FILE"
else
echo "❌ No current PR draft found."
echo "💡 Run '/idd-pr new' to generate one."
fi
#!/bin/bash
# Load helper libraries
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIBS_DIR="$SCRIPT_DIR/_libs"
. "$LIBS_DIR/idd-session.lib.sh"
REPO_ROOT=$(git rev-parse --show-toplevel)
PR_DIR="$REPO_ROOT/temp/idd/pr"
OUTPUT_FILE=$(_load_last_file "$PR_DIR" "pr_current_draft.md")
DRAFT_FILE="$PR_DIR/$OUTPUT_FILE"
EDITOR="${EDITOR:-code}"
if [[ -f "$DRAFT_FILE" ]]; then
echo "📝 Opening in editor: $EDITOR"
$EDITOR "$DRAFT_FILE"
echo "✅ Draft opened in editor"
else
echo "❌ No current PR draft found."
echo "💡 Run '/idd-pr new' to generate one."
fi
#!/bin/bash
# Load helper libraries
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LIBS_DIR="$SCRIPT_DIR/_libs"
. "$LIBS_DIR/idd-session.lib.sh"
REPO_ROOT=$(git rev-parse --show-toplevel)
PR_DIR="$REPO_ROOT/temp/idd/pr"
OUTPUT_FILE=$(_load_last_file "$PR_DIR" "pr_current_draft.md")
DRAFT_FILE="$PR_DIR/$OUTPUT_FILE"
if [[ ! -f "$DRAFT_FILE" ]]; then
echo "❌ No current PR draft found."
echo "💡 Run '/idd-pr new' to generate one."
exit 1
fi
# Extract title from first line (H1 heading)
TITLE=$(head -n 1 "$DRAFT_FILE" | sed 's/^# *//')
if [[ -z "$TITLE" ]]; then
echo "❌ Could not extract title from draft"
echo "💡 First line should be an H1 heading (# Title)"
exit 1
fi
# Determine base branch (parent branch of current branch)
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
BASE_BRANCH="main"
# Find parent branch by checking merge-base with all branches
BEST_DISTANCE=999999
CANDIDATES=()
for branch in $(git for-each-ref --format='%(refname:short)' refs/heads/ refs/remotes/origin/ | grep -v "$CURRENT_BRANCH" | grep -v "^origin$"); do
# Skip remote tracking branches if local exists
if [[ "$branch" =~ ^origin/ ]]; then
LOCAL_NAME="${branch#origin/}"
if git show-ref --verify --quiet "refs/heads/$LOCAL_NAME"; then
continue
fi
fi
# Calculate merge-base and distance
MERGE_BASE=$(git merge-base "$CURRENT_BRANCH" "$branch" 2>/dev/null || echo "")
if [[ -n "$MERGE_BASE" ]]; then
DISTANCE=$(git rev-list --count "$MERGE_BASE..$CURRENT_BRANCH")
if [[ $DISTANCE -gt 0 ]]; then
if [[ $DISTANCE -lt $BEST_DISTANCE ]]; then
BEST_DISTANCE=$DISTANCE
CANDIDATES=("$branch")
elif [[ $DISTANCE -eq $BEST_DISTANCE ]]; then
CANDIDATES+=("$branch")
fi
fi
fi
done
# If multiple candidates with same distance, prioritize main/master
FOUND_MAIN=false
for candidate in "${CANDIDATES[@]}"; do
CLEAN_NAME="${candidate#origin/}"
if [[ "$CLEAN_NAME" == "main" ]] || [[ "$CLEAN_NAME" == "master" ]]; then
BASE_BRANCH="$CLEAN_NAME"
FOUND_MAIN=true
break
fi
done
# If no main/master found, use first candidate
if [[ "$FOUND_MAIN" == false ]] && [[ ${#CANDIDATES[@]} -gt 0 ]]; then
BASE_BRANCH="${CANDIDATES[0]#origin/}"
fi
echo "🚀 Creating PR: $TITLE"
echo "📌 Base branch: $BASE_BRANCH (detected parent)"
# Extract body (skip H1 title and empty line)
BODY_FILE="$PR_DIR/pr_body.txt"
tail -n +3 "$DRAFT_FILE" > "$BODY_FILE"
# Create PR using GitHub CLI with auto-detected base branch
if gh pr create --base "$BASE_BRANCH" --title "$TITLE" --body-file "$BODY_FILE"; then
echo "🎉 PR successfully created!"
# Clean up draft and temporary files
rm -f "$DRAFT_FILE"
rm -f "$LAST_DRAFT"
rm -f "$BODY_FILE"
echo "🗑️ Draft file cleaned up"
else
echo "❌ GitHub CLI error"
echo "💡 Tip: Make sure you have push permissions and gh CLI is authenticated"
rm -f "$BODY_FILE"
exit 1
fi
gh pr create による PR 作成/idd-pr new コマンドは以下の流れで動作:
/idd-pr new [--output=file] を実行pr_current_draft.md).github/PULL_REQUEST_TEMPLATE.md 読み込みtemp/idd/pr/{output_file} に保存/idd-pr push コマンドは以下の流れで動作:
temp/idd/pr/ から最後に生成されたドラフトを読み込みgh pr create を使用して GitHub に PR を作成This project is licensed under the MIT License. Copyright (c) 2025 atsushifx