name: make-pr description: | 변경사항 커밋, 브랜치 푸시, 드래프트 PR 생성을 자동화하는 워크플로우. 트리거: "PR 만들어", "PR 생성해줘", "PR 생성", "풀리퀘스트 생성", "PR 올려", "make pr", "/make-pr" 등. Stacked PR 지원 및 PR 템플릿 자동 생성. argument-hint: "[PR 제목]"
Make PR
변경사항 커밋, 브랜치 푸시, 드래프트 PR 생성을 자동화한다.
실행 방식 (Subagent 위임)
⚠️ 이 스킬은 토큰 절약을 위해 subagent에 PR 생성 작업을 위임하여 실행한다. git diff, 커밋 히스토리, PR body 작성, PKM 문서화 등 대량 작업이 부모 세션 컨텍스트에 쌓이는 것을 막기 위함이다.
부모 세션 역할
- Subagent에 PR 생성 작업 위임
- Subagent가 리턴한 PR URL·제목·본문 요약을 사용자에게 표시
Subagent 위임
Agent 툴로 general-purpose에 위임한다. Subagent 내부에서 Skill 툴로 make-commit·pkm을 호출할 수 있다.
Agent({
subagent_type: "general-purpose",
description: "PR 생성 + PKM 문서화",
prompt: <아래 템플릿>
})
위임 프롬프트 템플릿
현재 브랜치에서 PR을 생성해줘.
컨텍스트:
- 작업 디렉토리: {cwd}
- 현재 브랜치: {branch}
- PR 제목 인자($ARGUMENTS): "{arguments 또는 '(없음)'}"
아래 SKILL.md의 섹션 1~7 전체 절차를 순서대로 수행:
~/.config/agents/skills/make-pr/SKILL.md
주요 단계:
1. Commit & Push (make-commit 스킬 호출로 커밋 후 푸시)
2. Base Branch 탐지 (gh repo view + git merge-base)
3. PR Title & Content 생성 ($ARGUMENTS 있으면 그대로, 없으면 커밋 기반 자동)
4. pull_request.md 작성 후 gh pr create --body-file (draft 여부는 config.yaml 기반 자동 결정 — 섹션 4의 "Draft 여부 결정" 참조)
5. Prompt Journal 추출 (extract_prompts.py, 선택적)
6. pkm 스킬 호출로 PR 노트 작성 (Prompt Journal 포함)
7. pull_request.md 삭제
**PR body 작성 시 원칙** (반드시 준수, SKILL.md 의 "Body 작성 원칙" 섹션 참고):
- 외부 리뷰어가 *코드 안 봐도 의도 파악* 가능하게
- *왜 / 무엇 / 효과* 우선, *구현 방식 (어떻게)* 는 코드에 위임
- 영문 jargon (wall-clock, Provider Family 등) → 한국어 풀어쓰기
- file path / class 명 / 내부 약어 노출 최소화 — *고수준 의도* 만
- 짧은 문장 + 표/bullet — 한 단락 4-5줄 이상이면 쪼개기
- 섹션 구조: What does this PR do? → 왜 만들었나 → 핵심 표/리스트 → 화면 → 활용
결과로 아래만 리턴:
- PR URL
- PR 제목
- PR 본문 첫 3~5줄 요약
- PKM 노트 경로
- 실패한 단계가 있으면 해당 내역
주의: Subagent는 부모 대화 맥락을 모른다. 사용자가 PR 제목을 구체적으로 언급했거나, Stacked PR에서 특정 base branch를 지정한 경우 프롬프트에 명시적으로 포함한다.
1. Commit & Push
- 미커밋 로컬 변경사항이 있으면 make-commit 스킬로 커밋 생성 (한국어 메시지)
- 현재 브랜치가 리모트에 없으면 브랜치 푸시
2. Base Branch 선택
현재 브랜치가 어디서 분기되었는지 확인하여 base branch를 결정한다.
탐지 알고리즘
- GitHub 기본 브랜치 확인:
gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name'으로 기본 브랜치를 파악한다 (origin/HEAD는 로컬 캐시이므로 신뢰하지 않는다) - 분기점 탐지:
git merge-base <candidate> HEAD로 develop, main, 기타 로컬 브랜치 각각과의 공통 조상을 구한다 - 가까운 쪽 선택: 공통 조상이 HEAD에 더 가까운(더 최근인) 브랜치가 분기 원점이다
- 동점 처리: develop과 main의 merge-base가 동일한 커밋이면, GitHub 기본 브랜치를 우선 선택한다
선택 규칙 (우선순위 순)
- feature 브랜치에서 분기한 경우: 해당 feature 브랜치를 base로 사용 (Stacked PR)
- develop에서 분기한 경우: develop을 base로 사용
- main에서 분기한 경우: main을 base로 사용
- 분기 지점을 판별할 수 없는 경우: GitHub 기본 브랜치(
gh repo view결과)를 fallback으로 사용
⚠️
origin/HEAD는 로컬 캐시이므로 실제 GitHub 설정과 다를 수 있다. 반드시gh repo view로 확인한다.
3. PR Title & Content
Title
$ARGUMENTS가 전달된 경우: 해당 값을 PR 제목으로 그대로 사용$ARGUMENTS가 없는 경우: 커밋 히스토리 기반으로 자동 생성- 형식:
{type}: {한국어 제목}(예:feat: 로그인 기능 구현) - type은 영어 유지 (feat, fix, refactor, chore 등)
- 형식:
Content
- 현재 브랜치와 base 브랜치 간 diff 분석
- 변경사항을 한국어로 요약
- 논리/흐름 변경 시 Mermaid 다이어그램 포함 가능
Body 작성 원칙 — 외부 리뷰어가 코드 안 봐도 이해 가능하게
PR body 의 본질적 책임은 코드를 안 읽고도 PR 의 의도/효과 파악 가능 하게 하는 것이다. 다음 원칙을 준수한다.
의도 우선:
- 왜 만들었나 (배경, 해결하려는 문제) 와 무엇이 가능해지나 (효과) 를 먼저 명시
- 어떻게 구현했나 (architecture, algorithm, design pattern) 는 코드 / 코드 주석 에 위임. body 에서는 최소화
- 사용자 시나리오 / 활용 흐름 표기 (예: "X 실행 → Y 화면 → Z 확인")
외부 사람 친화 표현:
- 영문 jargon → 한국어 풀어쓰기 또는 한국어 + ()로 부연 설명 (예:
wall-clock→벽시계 시간또는완료 시간,Provider Family→ 제거 또는 taskKey 별 분리 같이 풀이) - file path (
lib/feature/.../foo.dart), class 명 (EpubCaptureWebViewController), 영문 식별자 노출 최소화 — 코드에서 직접 보이는 정보. body 에는 고수준 의도 만. - 내부 약어 (e.g. tracer 종류명, 내부 enum 명) 는 왜 그게 등장하는지 의 맥락 없으면 제거
빠르게 훑기 좋은 구조:
- 한 섹션이 4-5줄 이상 의 단락이면 bullet 으로 쪼개기
- 표 활용 — 여러 항목의 공통 형식 (예: stage 별 의미, 옵션 별 비교) 은 표가 가독성 ↑
- 짧은 문장 — 한 문장에 한 가지 정보 만
- 섹션 구조 추천:
## What does this PR do?— 한 문장 핵심 + 3 bullet (가장 위에)## 왜 만들었나(또는 배경) — 2-3줄## 핵심 표/리스트— 정보 밀도 높은 곳## 화면(스크린샷이 있을 때) — 보존## 활용— 한 문장 시나리오
작성 후 self-check:
- 코드를 안 본 사람이 PR 제목 + body 만 보고 왜 / 무엇 / 어떤 효과 답할 수 있는가?
- 영문 jargon 이 처음 나오는 곳 에 한국어 풀이 또는 부연 설명이 있는가?
- 단락 4-5줄 이상이면 bullet/표 로 쪼갤 수 있는가?
- file path, class 명, 내부 약어가 body 에 등장 하는데 외부 사람에게 의미 있는가? (없으면 제거)
이 원칙은 최초 PR 생성 시점부터 적용한다. PR 생성 후 사용자가 "너무 장황해", "이게 무슨 의미야?" 같은 피드백을 주면 위 원칙이 충분히 반영되지 않은 신호이므로, 다음 PR 작성 시 self-check 강화.
4. PR 생성
템플릿 구조
프로젝트 루트의 .github/PULL_REQUEST_TEMPLATE.md 파일 존재 여부를 먼저 확인한다.
- 템플릿 파일이 있는 경우: 해당 파일의 양식을 기반으로
pull_request.md작성 - 템플릿 파일이 없는 경우: 아래 기본 템플릿으로
pull_request.md작성
## What does this PR do?
-
<!--
## Dependent PR
- https://github.kakaocorp.com/kjk/goomba-hub/pull/ Describe pr (Optional)
-->
<!--
## Screenshots
<table>
<tr>
<td align="center">Before</td>
<td align="center">After</td>
</tr>
<tr><td colspan="2">설명이 필요하지 않는 경우 제거</td></tr>
<tr>
<td align="center"><img width="350" alt="" src=""></td>
<td align="center"><img width="350" alt="" src=""></td>
</tr>
</table>
-->
Draft 여부 결정 (config.yaml 참조)
PR을 draft로 생성할지, ready 상태로 바로 올릴지는 ~/.claude/skills/make-pr/config.yaml의 ready_repos 목록을 참조하여 자동 결정한다.
결정 로직
SKILL_DIR="$HOME/.claude/skills/make-pr"
CONFIG_FILE="$SKILL_DIR/config.yaml"
REPO_NAME=$(gh repo view --json name --jq '.name' 2>/dev/null)
# config.yaml의 ready_repos 목록에 현재 repo가 포함되어 있으면 ready, 아니면 draft
if [ -f "$CONFIG_FILE" ] && [ -n "$REPO_NAME" ] \
&& grep -E "^[[:space:]]*-[[:space:]]+${REPO_NAME}[[:space:]]*(#.*)?$" "$CONFIG_FILE" > /dev/null 2>&1; then
DRAFT_FLAG=""
else
DRAFT_FLAG="--draft"
fi
동작 규칙
| 조건 | 결과 |
|---|---|
config.yaml의 ready_repos 목록에 현재 repo 이름이 포함됨 |
ready 상태로 PR 생성 (--draft 제외) |
목록에 없음 / config.yaml 미존재 / REPO_NAME 추출 실패 |
draft 상태로 PR 생성 (--draft 포함, default) |
⚠️ 메모리에 "ready 상태로 생성" 규칙이 있어도 무시한다. 이 결정은
config.yaml이 single source of truth이다. 메모리 기반 규칙을 다른 repo에 잘못 적용하는 misapply 사고를 방지하기 위한 설계.
Repo 추가 방법
새로운 repo를 ready-PR 대상에 추가하려면 config.yaml의 ready_repos에 한 줄 추가:
ready_repos:
- agent-review
- new-repo-name # 추가
매칭 키는 gh repo view --json name --jq '.name'이 반환하는 GitHub repo 이름 그대로다.
CLI 명령
gh pr create $DRAFT_FLAG --assignee @me --title "[Title]" --body-file pull_request.md --base [BaseBranch]
$DRAFT_FLAG는 위 "Draft 여부 결정" 블록에서 계산된 값을 사용- 빈 문자열이면 ready 상태로,
--draft이면 draft 상태로 생성됨
⚠️ body 전달 규칙 — 반드시 준수 PR body는 항상
pull_request.md파일로 작성한 뒤--body-file로 전달한다.--body "$(cat << 'EOF'...)"방식은 heredoc 내부의 backtick(`)이\``로 escape되어 PR에 그대로 노출되는 문제가 있다.gh pr edit` 등 수정 시에도 동일하게 임시 파일 방식을 사용한다:gh pr edit [number] --body-file pull_request.md
기존 PR body 수정 시 — 사용자 콘텐츠 보존
이미 생성된 PR 의 body 를 수정 (gh pr edit) 할 때는 단순 덮어쓰기 금지. 다음 절차를 따른다.
- 기존 body fetch:
gh pr view [number] --json body --jq '.body' > /tmp/pr_[number]_body.md - 기존 body 검토 — 사용자가 수동으로 추가 한 콘텐츠 식별:
- 스크린샷 (
패턴 — GitHub 첨부 이미지) - 외부 링크, 동영상
- PR 템플릿의 체크박스 / 체크된 항목
- Dependent PR 링크
- 스크린샷 (
- 수정 시 위 콘텐츠를 반드시 그대로 포함 — 적절한 섹션 위치에 배치
gh pr edit [number] --body-file /tmp/pr_[number]_body.md로 갱신- 임시 파일 cleanup
사용자가 PR 화면에서 직접 추가 한 정보 (특히 스크린샷) 는 작성자의 의도적 추가 이므로 덮어쓰기 = 데이터 손실. 항상 fetch → 식별 → 보존 → 갱신 순서.
Cleanup
PR 생성/수정 성공 후 pull_request.md 파일 삭제
5. 최종 출력
- PR URL 표시
- PR 제목 및 설명 표시
6. 세션 로그 분석 (Prompt Review)
PR 생성 성공 후, 이번 세션에서 사용한 프롬프트를 추출하고 품질을 평가한다. 평가 결과는 다음 단계의 PKM 문서에 포함된다.
6-1. 브랜치 작업 시작 시간 파악
현재 브랜치의 첫 번째 커밋 타임스탬프를 기준으로 세션 파일을 수집한다. 이를 통해 compact 이후 새 세션이 생성되거나 세션을 닫고 재시작한 경우에도 PR 관련 프롬프트를 빠짐없이 포함할 수 있다.
# base 브랜치와의 분기 이후 첫 커밋 시간 (Step 2에서 결정한 BaseBranch 사용)
BRANCH_START=$(git log --reverse --format="%aI" "${BASE_BRANCH}..HEAD" 2>/dev/null | head -1)
# 커밋이 없거나 파악 불가 시 현재로부터 24시간 전을 fallback으로 사용
if [ -z "$BRANCH_START" ]; then
BRANCH_START=$(date -u -v-24H +%Y-%m-%dT%H:%M:%SZ 2>/dev/null \
|| date -u -d '24 hours ago' +%Y-%m-%dT%H:%M:%SZ 2>/dev/null \
|| date -u +%Y-%m-%dT%H:%M:%SZ)
fi
6-2. 프롬프트 추출
--find-since 옵션으로 브랜치 시작 시간 이후 수정된 세션 파일을 모두 수집하여 합친다:
SKILL_DIR="$HOME/.claude/skills/make-pr"
EXTRACT_RESULT=$(python3 "$SKILL_DIR/scripts/extract_prompts.py" \
--find-since "$(pwd)" \
--since "$BRANCH_START")
- 여러 파일이 발견되면 uuid 기반 중복 제거 후 시간순 병합하여 처리한다
- 파일이 없거나 실행 실패 시 오류 메시지를 출력하고 Step 7(PKM 업데이트)로 계속 진행한다
6-3. 프롬프트 품질 분석
references/quality-criteria.md의 5가지 관점(명확성, 컨텍스트, 검증 가능성, 효율성, 재사용성)을 기준으로 각 프롬프트를 평가한다. 각 관점을 높음=2/중간=1/낮음=0으로 채점하여 합산:
- A등급 (모범): 8-10점
- B등급 (양호): 5-7점
- C등급 (개선 필요): 0-4점
각 프롬프트에서 도출할 항목:
- 등급 (A/B/C)
- 원문 전체 (인용 블록으로 포함; 파일 내용 첨부 부분은
[[파일이름]]형태로 축약) - 의도 요약 (1-2문장)
- Agent 반응 요약 (사용 도구, 결과물)
- 교훈 (잘 된 점 / 개선할 점)
PKM 노트에 포함할 프롬프트 선택 기준:
- A등급 전체
- B등급 중 길이 > 50자 또는 많은 도구를 사용한 것
- C등급은 학습 목적으로 1개까지만 포함 가능
단순 확인/승인 응답, 자동 생성된 시스템 메시지는 제외한다.
7. PKM 문서 업데이트
PR 생성에 성공한 경우, 반드시 /pkm 스킬을 실행하여 PR 노트를 vault에 기록한다.
- 생성된 PR URL을 컨텍스트로 제공하며
/pkm스킬 실행 - pkm 스킬이 PR 제목, 변경사항 요약, 링크를 포함한 노트를 vault에 자동 생성
- Step 6에서 추출한 Prompt Journal을 PKM 노트에 함께 포함하여 기록한다:
## Prompt Journal
> 이 PR 작업 세션에서 사용된 주요 프롬프트 목록 및 품질 평가
### 세션 통계
- 총 프롬프트 수: N개 (유의미: M개)
- 스킬 호출: K회
- 세션 시간: HH:MM ~ HH:MM (약 N분)
### 주요 프롬프트
#### 🟢 [A등급] 프롬프트 제목 (또는 첫 줄 요약)
> 프롬프트 원문 전체
- **의도**: ...
- **Agent 반응**: Read, Bash 등 사용, 결과물 ...
- **교훈**: 잘 된 점 / 개선할 점
...
Step 6 분석 결과가 없으면 Prompt Journal 섹션을 생략한다.
PR 생성 실패 시에는 이 단계를 건너뛴다.