# jira-my-tasks > 내게 할당된 Jira 이슈 조회, 마감일 알림, 대화형 코멘트 작성. 현재 사용자를 자동 감지하여 할당된 이슈 대시보드를 출력하고, 선택한 이슈에 작업 코멘트를 게시한다. - Author: hnc-minjae - Repository: hnc-minjae/claude-plugin - Version: 20260208222957 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-08 - Source: https://github.com/hnc-minjae/claude-plugin - Web: https://mule.run/skillshub/@@hnc-minjae/claude-plugin~jira-my-tasks:20260208222957 --- --- name: jira-my-tasks description: 내게 할당된 Jira 이슈 조회, 마감일 알림, 대화형 코멘트 작성. 현재 사용자를 자동 감지하여 할당된 이슈 대시보드를 출력하고, 선택한 이슈에 작업 코멘트를 게시한다. user_invocable: true --- # 내 작업 조회 워크플로우 참조: [MY_TASKS_CONFIG.md](MY_TASKS_CONFIG.md) ## Step 0: 환경 검증 `JIRA_USER`, `JIRA_TOKEN` 환경변수 확인 → 미설정 시 안내 후 중단. ```bash curl -s -u "$JIRA_USER:$JIRA_TOKEN" \ "https://your-domain.atlassian.net/rest/api/3/myself" \ -H "Accept: application/json" -w "\nHTTP_STATUS:%{http_code}" ``` HTTP 200이 아니면 중단. 응답에서 추출: - `displayName` → 대시보드 헤더에 표시 - `accountId` → JQL `assignee` 값으로 사용 (currentUser() 대신 직접 지정 시) ## Step 1: 이슈 조회 [MY_TASKS_CONFIG.md](MY_TASKS_CONFIG.md)의 JQL 설정을 확인한다. - **커스텀 JQL**이 비어있지 않으면 → 커스텀 JQL 사용 - 비어있으면 → 기본 JQL: `assignee = currentUser() AND status != Done ORDER BY duedate ASC` ```bash curl -s -u "$JIRA_USER:$JIRA_TOKEN" \ "https://your-domain.atlassian.net/rest/api/3/search/jql" -G \ --data-urlencode "jql={JQL}" \ --data-urlencode "fields=key,summary,status,priority,duedate,created,updated,issuetype,project,labels,components,fixVersions" \ --data-urlencode "maxResults=100" --data-urlencode "startAt=0" \ -H "Accept: application/json" ``` > `total > maxResults`이면 `startAt`을 증가시키며 반복하여 전체 이슈를 수집한다. 각 이슈에서 추출: - `key` — 이슈 키 (예: PROJ-123) - `fields.summary` — 제목 - `fields.status.name` — 상태 - `fields.priority.name` — 우선순위 - `fields.duedate` — 마감일 (ISO 날짜 또는 null) - `fields.issuetype.name` — 이슈 유형 - `fields.project.key` — 프로젝트 키 - `fields.updated` — 최종 수정일 ## Step 2: 마감일 분석 [MY_TASKS_CONFIG.md](MY_TASKS_CONFIG.md)의 **임박 기준일** (기본 7일)을 참조한다. 오늘 날짜를 기준으로 각 이슈를 분류: | 분류 | 조건 | 표시 | |------|------|------| | 기한 초과 | `duedate < 오늘` | `[초과 D+N]` (빨간색 강조) | | 임박 | `오늘 ≤ duedate ≤ 오늘 + 기준일` | `[D-N]` | | 여유 | `duedate > 오늘 + 기준일` | `[D-N]` | | 미설정 | `duedate == null` | `[기한 없음]` | ## Step 3: 대시보드 출력 ### 요약 헤더 ``` 📋 {displayName}님의 작업 현황 ({오늘 날짜}) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 전체 {N}건 | 기한 초과 {N}건 | 임박 {N}건 | 여유 {N}건 | 미설정 {N}건 ``` ### 기한 초과 섹션 (해당 이슈가 있을 때만) ``` 🚨 기한 초과 | # | 이슈 | 제목 | 상태 | 마감일 | 초과일 | |---|------|------|------|--------|--------| | 1 | PROJ-123 | 제목... | 진행 중 | 2026-02-01 | D+7 | ``` ### 마감 임박 섹션 (해당 이슈가 있을 때만) ``` ⚠️ 마감 임박 (7일 이내) | # | 이슈 | 제목 | 상태 | 마감일 | 남은일 | |---|------|------|------|--------|--------| | 2 | PROJ-456 | 제목... | 대기 | 2026-02-12 | D-4 | ``` ### 전체 이슈 목록 [MY_TASKS_CONFIG.md](MY_TASKS_CONFIG.md)의 상태 매핑을 적용하여 상태별로 그룹핑한다. ``` 📊 상태별 이슈 목록 ▸ 진행 중 (N건) | # | 이슈 | 제목 | 우선순위 | 마감일 | 프로젝트 | |---|------|------|----------|--------|----------| | 1 | PROJ-123 | 제목... | High | 2026-02-01 [D+7] | PROJ | ▸ 대기 (N건) | # | 이슈 | 제목 | 우선순위 | 마감일 | 프로젝트 | |---|------|------|----------|--------|----------| | 2 | PROJ-456 | 제목... | Medium | 2026-02-12 [D-4] | PROJ | ``` > 빈 상태 그룹은 출력하지 않는다. 각 이슈에는 대시보드 전체에서 고유한 **번호(#)** 를 부여한다 (코멘트 작성 시 선택용). ## Step 4: 코멘트 작성 여부 확인 대시보드 출력 후 사용자에게 묻는다: ``` 💬 코멘트를 작성할 이슈를 선택하세요: - 번호 입력 (예: 1,3,5) - "all" — 전체 이슈에 코멘트 - "skip" — 코멘트 없이 종료 ``` AskUserQuestion 도구를 사용하여 사용자 입력을 받는다. - **skip** → Step 6으로 이동 - **all** → 전체 이슈 목록을 대상으로 Step 5 진행 - **번호** → 해당 번호의 이슈만 대상으로 Step 5 진행 (잘못된 번호는 무시하고 안내) ## Step 5: 코멘트 작성 및 게시 선택된 각 이슈에 대해 순서대로: ### 5-1: 코멘트 내용 입력 ``` 📝 [{이슈키}] {제목} 작업 내용을 입력하세요: ``` AskUserQuestion 도구로 사용자 입력을 받는다. ### 5-2: ADF 변환 및 게시 입력받은 텍스트를 Atlassian Document Format(ADF)으로 변환하여 게시한다. Python으로 ADF JSON을 생성한다: ```bash python3 -c " import json, sys text = sys.argv[1] lines = [l.strip() for l in text.strip().split('\n') if l.strip()] # 여러 줄이면 bulletList, 한 줄이면 paragraph if len(lines) > 1: items = [] for line in lines: # '- ' 또는 '* ' 접두사 제거 clean = line.lstrip('-*').strip() items.append({ 'type': 'listItem', 'content': [{ 'type': 'paragraph', 'content': [{'type': 'text', 'text': clean}] }] }) body_content = [{'type': 'bulletList', 'content': items}] else: body_content = [{ 'type': 'paragraph', 'content': [{'type': 'text', 'text': lines[0]}] }] payload = { 'body': { 'type': 'doc', 'version': 1, 'content': body_content } } json.dump(payload, open('/tmp/jira-my-tasks-comment.json', 'w'), ensure_ascii=False) " "{입력받은 텍스트}" ``` 게시: ```bash curl -s -u "$JIRA_USER:$JIRA_TOKEN" \ -X POST "https://your-domain.atlassian.net/rest/api/3/issue/{이슈키}/comment" \ -H "Content-Type: application/json" \ -d @/tmp/jira-my-tasks-comment.json \ -w "\nHTTP_STATUS:%{http_code}" ``` HTTP 201이면 성공: ``` ✅ [{이슈키}] 코멘트 게시 완료 ``` 실패 시 에러 메시지 출력 후 다음 이슈로 계속 진행한다. ## Step 6: 정리 및 종료 임시 파일 삭제: ```bash rm -f /tmp/jira-my-tasks-comment.json ``` 최종 요약: ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ 작업 완료 📊 조회: 전체 {N}건 (초과 {N} / 임박 {N} / 여유 {N} / 미설정 {N}) 💬 코멘트: {게시 건수}건 게시 완료 ``` 코멘트를 작성하지 않았으면 코멘트 줄은 생략한다. ## 에러 처리 | 상황 | 대응 | |------|------| | 환경변수 미설정 | `JIRA_USER`, `JIRA_TOKEN` 설정 안내 후 중단 | | 인증 실패 (401/403) | 토큰 확인 안내 후 중단 | | API 실패 (5xx) | 1회 재시도, 실패 시 에러 출력 후 중단 | | 이슈 0건 | "할당된 이슈가 없습니다" 출력 후 종료 | | 코멘트 게시 실패 | 해당 이슈 에러 출력, 나머지 이슈 계속 진행 | | JQL 구문 오류 (400) | JQL 확인 안내, MY_TASKS_CONFIG.md 참조 유도 |