Help us improve
Share bugs, ideas, or general feedback.
From jira-integration
Locally merges a Jira task branch into its base branch without a remote or pull request. Handles auto-commit, Jira status transitions, and worktree cleanup.
npx claudepluginhub mzd-hseokkim/jira-claude-code-integration --plugin jira-integrationHow this skill is triggered — by the user, by Claude, or both
Slash command
/jira-integration:jira-local-merge <TASK-ID><TASK-ID>This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Language Rule**: 프로젝트 CLAUDE.md의 Conventions 섹션 참고 (한국어 출력, Jira 코멘트 제목은 영어).
Guides technical evaluation of code review feedback: read fully, restate for understanding, verify against codebase, respond with reasoning or pushback before implementing.
Share bugs, ideas, or general feedback.
Language Rule: 프로젝트 CLAUDE.md의 Conventions 섹션 참고 (한국어 출력, Jira 코멘트 제목은 영어).
remote origin 없이 feature 브랜치를 base 브랜치로 로컬 병합하고, Jira 상태 전환 및 worktree 정리까지 일괄 처리한다.
이 스킬에서 mcp__atlassian__jira_get_issue를 호출하는 경우 다음 파라미터를 사용한다 (병합/전환에 필요한 메타만):
fields="summary,status,issuetype"comment_limit=0.jira-context.json을 읽어 태스크 컨텍스트 로드:
taskId, branch, baseBranch, worktreePath, repoRoot인자로 TASK-ID가 전달된 경우 해당 값 우선 사용.
repoRoot가 없으면 git worktree list의 첫 번째 줄로 폴백:
# git worktree list 첫 번째 줄이 항상 메인 레포 경로
git worktree list | head -1 | awk '{print $1}'
git worktree list --porcelain | awk 'NR==2{print $2; exit}'도 동일 결과.
git rev-parse --show-toplevel은 워크트리 안에서는 워크트리 경로를 반환하므로 사용하지 않음.
baseBranch가 없으면 repoRoot에서 감지:
git -C "<repoRoot>" rev-parse --verify develop 2>/dev/null
git -C "<repoRoot>" rev-parse --verify main 2>/dev/null
git -C "<repoRoot>" rev-parse --verify master 2>/dev/null
# 1. feature 브랜치 존재 확인
git branch --list "feature/<TASK-ID>"
# 2. 워크트리 내 미커밋 변경사항 확인
git -C "<worktreePath>" status --porcelain
미커밋 변경사항이 있으면 사용자에게 묻지 않고 스마트 커밋한다. merge 요청 자체가 "커밋도 끝났길 바란다"는 의도이므로 흐름을 끊지 않는다.
.gitignore가 이미 거르는 항목(.jira-context.json, TASK-README.md 등)은 자연히 빠진다.cd "<worktreePath>"
# junk 제외하고 의미 있는 변경만 스테이징
git add -A -- . \
':(exclude,glob)**/*.log' ':(exclude,glob)**/*.tmp' ':(exclude,glob)**/*.swp' \
':(exclude)nul' ':(exclude)**/.DS_Store' ':(exclude)**/Thumbs.db'
# 스테이징된 변경이 있을 때만 커밋
if ! git diff --cached --quiet; then
git commit -m "feat(<TASK-ID>): <issue summary>"
fi
스테이징할 의미 있는 변경이 없으면 커밋을 생략하고 다음 단계로 진행한다.
병합 전략은 항상 --no-ff (merge commit 생성, feature 브랜치 히스토리 보존)로 고정한다. 사용자에게 묻지 않는다 — merge를 요청했다는 것은 전략이 이미 정해져 있다는 의미다.
.jira-context.json의 repoRoot를 사용한다. git rev-parse --show-toplevel은 워크트리 안에서 실행하면 워크트리 경로를 반환하므로 사용하지 않음.
git -C "<repoRoot>" checkout <baseBranch>
git -C "<repoRoot>" merge --no-ff feature/<TASK-ID> -m "Merge feature/<TASK-ID>: <issue summary>"
merge 충돌 발생 시 사용자에게 알리고 중단. 충돌 해결 후 재실행 안내.
mcp__atlassian__jira_add_comment로 병합 결과 게시:
## Task Merged Locally: <TASK-ID>
**브랜치**: feature/<TASK-ID> → <baseBranch>
**전략**: --no-ff
**커밋 수**: <count>개
**변경 파일**: <count>개 (+<추가> -<삭제>)
### Changes
<git log --oneline 요약>
mcp__atlassian__jira_get_transitions로 전환 목록 조회 후 mcp__atlassian__jira_transition_issue로 상태 전환:
jira-task done에서 처리)ADF comment 경고 및 호출 패턴: Read skills/_shared/transition-verify.md 의 "ADF Comment 경고" 섹션 준수.
Read skills/_shared/transition-verify.md — fresh fetch 절차, <final-jira-status> 결정 규칙, fetch 실패 정책을 그대로 따른다. 결과 status를 Step 8의 <final-jira-status> 인자로 전달.
현재 Claude Code가 워크트리 디렉토리에서 실행 중이므로 워크트리를 직접 삭제할 수 없다. 병합이 완료된 후 사용자에게 아래 안내를 출력한다:
⚠️ 워크트리 정리가 필요합니다.
이 세션을 닫고 메인 레포에서 아래 명령을 실행하세요:
git worktree remove "<worktreePath>" --force
⚠️ feature 브랜치(feature/<TASK-ID>)는 삭제하지 마세요.
PR 생성에 필요합니다. PR 머지 후 삭제하세요.
실제 명령 실행은 하지 않는다.
워크트리의 .jira-context.json과 <repoRoot>/.jira-context.json 양쪽을 공용 스크립트로 갱신한다. 스크립트 경로 결정은 Read skills/_shared/script-lookup.md 후 lookup 블록 실행:
SCRIPT_NAME="jira-context-update.py" OUT_VAR="JIRA_CTX_UPDATE_PY"
# Read skills/_shared/script-lookup.md and execute its lookup block here
python3 "$JIRA_CTX_UPDATE_PY" <TASK-ID> merge "<final-jira-status>" \
"<worktree>/.jira-context.json" \
"<repoRoot>/.jira-context.json"
<final-jira-status>: Step 6.5에서 fresh fetch로 확보한 Jira 실제 status명 (예: "In Review", "검토중"). transition 시도값을 그대로 쓰지 말 것.스크립트는 다음을 일괄 처리한다:
completedSteps에 "merge" 추가 (중복 방지)status를 <final-jira-status>로 setmergedAt에 현재 UTC ISO 8601 (Z suffix) 기록 — TZ-naive timestamp는 dashboard reader가 stale로 처리하므로 Z 접미사 필수cachedIssue.status / cachedIssue.fetchedAt도 함께 갱신 (cachedIssue가 있을 때만)tasks[]에서 해당 taskId 항목만 갱신)아래 형식으로 완료 요약 출력:
---
✅ **Local Merge Complete** — <TASK-ID>
- 병합: feature/<TASK-ID> → <baseBranch> (--no-ff)
- Jira 상태: In Review
- Worktree 정리: 세션 종료 후 수동 실행 필요 (위 안내 참고)
- feature 브랜치(feature/<TASK-ID>)는 PR 생성을 위해 보존됨
- 완료 리포트 Jira에 게시됨
**Progress**: init → start → approach → impl → test → review → **merge ✓** → pr → done
**Next**: 세션 종료 후 메인 레포에서 `/jira-task pr <TASK-ID>` — PR을 생성합니다
---