Skip to main content

plane

셀프호스팅 Plane(프로젝트 관리, Jira/Confluence 대체) REST API 워크벤치. 프로젝트/work item/사이클/모듈/코멘트/멤버/상태/라벨 CRUD + Jira→Plane 이관. 의존성 0(Python stdlib만), self-host 지원. 'plane', 'plane 이슈', '워크아이템', 'jira 옮겨', 'jira to plane', 'confluence 옮겨', '사이클', '모듈', 'work item', 'plane 프로젝트' 호출 시 사용.

Ir a la instalación

Datos de origen

Repositorio
junghan0611/agent-config
Última actividad en el origen
18 de junio de 2026 a las 08:46
Idioma detectado de SKILL.md
coreano
Estrellas
5
Forks
0

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Explorador de archivos
6 archivos

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
plane
description
셀프호스팅 Plane(프로젝트 관리, Jira/Confluence 대체) REST API 워크벤치. 프로젝트/work item/사이클/모듈/코멘트/멤버/상태/라벨 CRUD + Jira→Plane 이관. 의존성 0(Python stdlib만), self-host 지원. 'plane', 'plane 이슈', '워크아이템', 'jira 옮겨', 'jira to plane', 'confluence 옮겨', '사이클', '모듈', 'work item', 'plane 프로젝트' 호출 시 사용.
# Plane Skill — 셀프호스팅 프로젝트 관리 워크벤치 셀프호스팅 서버에 떠있는 Plane(Jira/Confluence 대체)을 REST API로 조작한다. 적재(load) 손이다. 추출(extract)은 `jiracli` 스킬이 담당 — 둘을 이어 Jira→Plane 이관. 베이스: `JinkoLLC/plane-skill`(MIT, 단일 스크립트·무의존) 벤더링 + 아이디어 차용: `cpatrickalves/plane-cli`(fuzzy 해석·커맨드 커버리지). ## 인증 / 설정 `~/.env.local` 에 저장됨 (비공개, gitignore). **호출 전 항상 `source ~/.env.local`.** ```bash export PLANE_API_KEY="plane_api_..." # Plane → Settings → API Tokens export PLANE_BASE_URL="http://localhost:3388" # 서버에서 직접(=CF Access 회피) export PLANE_WORKSPACE="test" # 워크스페이스 슬러그 ``` - **서버에서 실행이 원칙**: `localhost:3388` 직격 → Cloudflare Zero Trust 로그인 게이트 회피. 노트북에서 굴리려면 `https://plane.<your-domain>` + CF service token 필요(지금은 오버). - API 인증 헤더: `X-API-Key`. 경로: `{BASE_URL}/api/v1/...`. ## 기본 사용 ```bash PLANE="$HOME/.claude/skills/plane/scripts/plane" source ~/.env.local # 내 정보 / 멤버 "$PLANE" me "$PLANE" members # 프로젝트 "$PLANE" projects list "$PLANE" projects get --project <PROJ_UUID> "$PLANE" projects create --name "마이그레이션" --identifier MIG --description "..." # work item (이슈) "$PLANE" issues list --project <PROJ_UUID> [--state <ID>] [--priority high] "$PLANE" issues get --project <PROJ_UUID> <ISSUE_UUID> "$PLANE" issues create --project <PROJ_UUID> --name "제목" \ --description "본문" --priority high "$PLANE" issues update --project <PROJ_UUID> <ISSUE_UUID> --state <STATE_ID> "$PLANE" issues assign --project <PROJ_UUID> <ISSUE_UUID> <USER_ID> [<USER_ID>...] "$PLANE" issues delete --project <PROJ_UUID> <ISSUE_UUID> "$PLANE" issues search --query "키워드" # 사이클(스프린트) / 모듈 "$PLANE" cycles list --project <PROJ_UUID> "$PLANE" cycles create --project <PROJ_UUID> --name "Sprint 1" \ --start-date 2026-06-18 --end-date 2026-07-01 "$PLANE" modules list --project <PROJ_UUID> "$PLANE" modules create --project <PROJ_UUID> --name "결제 모듈" # 코멘트 / 상태 / 라벨 "$PLANE" comments list --project <PROJ_UUID> --issue <ISSUE_UUID> "$PLANE" comments add --project <PROJ_UUID> --issue <ISSUE_UUID> --text "코멘트" "$PLANE" states --project <PROJ_UUID> # flat 커맨드(하위 list 없음) "$PLANE" labels --project <PROJ_UUID> # flat 커맨드(하위 list 없음) ``` `--format json` 으로 모든 출력 JSON 전환(스크립팅용). 기본은 컬러 테이블. ## Confluence → Markdown 트리 (`confluence_to_md.py`) Confluence 문서는 **Plane Pages(HTML/블록)가 아니라 순수 `.md` 파일 트리**로 끌어내린다. Plane Pages도 결국 `description_html` + collab binary 저장이라 "활용 가능한 포맷"이 아니다. **문서 SSOT = git 관리 md 트리.** Plane Pages 는 선택적 렌더 타겟일 뿐. ```bash PY="$HOME/.claude/skills/plane/scripts/confluence_to_md.py" source ~/.env.local # JIRA_HOST / JIRA_USER_EMAIL / JIRA_API_TOKEN # 스페이스 전체 (dry-run: 트리/카운트만) "$PY" --space QA --out ~/repos/gh/memex-kb/docs/confluence # 실제 추출 "$PY" --space QA --out <DIR> --apply # 단일 페이지 + 하위 트리 "$PY" --page-id 426033 --out <DIR> --apply ``` 설계 (선행 자산 통합): `jiracli/confluence_ingest.py`(REST+front matter) + `memex-kb/confluence_to_markdown.py`(cleanup + NFC) 를 흡수. - 소스 포맷 **`body-format=export_view`** — 매크로/코드/이미지가 이미 렌더된 정적 HTML. - pandoc `-t markdown`(**grid table** — `-t gfm` 은 colspan 표를 raw HTML 로 떨굼). - **한글**: export_view 는 소스부터 NFC라 pandoc 3.x 가 안 깨뜨림(실측). 그래도 마지막에 `unicodedata.normalize('NFC')` 안전망(NFD 페이지 자동 교정). *박살이 관측되면 pandoc 폐기.* - ancestors → 디렉토리 미러링, 첨부/이미지 → `_assets/<pageid>/` 다운로드 + 상대경로 치환. - front matter 에 `source_version` → **멱등**(버전 동일하면 skip). ### 문서에서 못 옮기는 것 (실측 경계) | 요소 | 결과 | |------|------| | 제목/본문/헤딩/리스트/링크 | ✅ 깔끔한 md | | 표 | ✅ grid table (`+---+`) — colspan 포함 | | 이미지/첨부 | ✅ 다운로드 + 상대경로 | | 한글 | ✅ NFC 보존 | | Confluence 매크로(jira/include/toc/drawio) | ⚠️ export_view 시점 정적 렌더로 흡수(동적기능 상실) | | inline comment / page restrictions / 버전 본문 | ❌ 유실(`source_version` 메타만) | ### (선택) md 트리 → Plane Pages 올리기 (`md_to_plane_pages.py`) md SSOT 를 Plane 안에서도 열람하려면 Pages 로 올린다. **pages-api-patch 오버레이 필수** (self-host v1 에 pages POST/PATCH 노출 — hej-kip/plane/pages-api-patch). ```bash PY="$HOME/.claude/skills/plane/scripts/md_to_plane_pages.py" "$PY" --dir <MD_DIR> --project <PLANE_PROJ_UUID> # dry-run "$PY" --dir <MD_DIR> --project <PLANE_PROJ_UUID> --apply # 업로드 ``` - md→html: pandoc `-f gfm -t html`. 멱등: page **title 매칭**(external_id 없음) → 있으면 PATCH. - ⚠️ **이미지**: md 의 `_assets/` 상대경로는 Plane 에서 안 풀린다(asset 업로드 미구현 — phase 2). 이미지까지 Plane 에 박으려면 generic asset API(`/workspaces/<slug>/assets/`) 업로드 필요. - 문서 SSOT 는 어디까지나 md 트리. Plane Pages 는 열람용 사본. ## Jira / Confluence → Plane 이관 데이터 동제권 경로: **Jira(클라우드) → 중립 포맷 → Plane(셀프호스트)**, 단방향·read-only 연습. (공식 임포터 UI는 Commercial 전용 — Community 셀프호스트엔 없음. 그래서 API 직접 이관이 정답.) ``` [jiracli: 추출] [변환] [plane: 적재] jira issue list -p X --raw → 필드 매핑(JSON) → plane issues create jira issue view KEY --raw ↓ plane comments add 상태/우선순위/유저 매핑 plane cycles/modules create ``` 추출 명령(jiracli, `--raw` = Jira API 원본 JSON): ```bash source ~/.env.local && jira issue list -p PROJ --raw # 프로젝트 전체 source ~/.env.local && jira issue view PROJ-123 --raw # 단건 상세(코멘트 포함) ``` ### 매핑 표 (Jira → Plane) | Jira | Plane | 비고 | |------|-------|------| | issue | work item | `name`=summary, `description_html`=description | | status | state | 프로젝트 state로 사전 매핑(`states`로 ID 확보) | | priority | priority | Highest/High→urgent/high, Medium→medium, Low/Lowest→low | | labels | labels | `labels`로 ID 매핑(없으면 생성) | | comments | comments | 작성자·시각은 본문에 prefix(API가 작성자 위조 불가) | | sprint | cycle | start/end date 보존 | | component | module | — | | assignee | assignee | Jira 이메일 → Plane member ID 매핑(`members`) | | parent/subtask | parent | 직계만 | | **custom field / epic / history** | ✗ | 안 넘어옴. 손매핑 or 라벨/본문에 흡수 | ### 멱등성(idempotency) `jira_to_plane.py` 는 Plane 네이티브 **`external_id`(=Jira key) + `external_source`(=jira:HOST)** 로 dedup — 재실행 시 409 로 기존 id 를 회수해 중복 생성 0(이름 prefix 불필요). **2-pass**: 1차 전량 생성(external_id/created_at/created_by/state/assignee) → 2차 부모(parent) 배선. 429 RATE_LIMIT 은 Retry-After/지수 백오프로 자동 재시도. **첫 실행은 `--limit` 소량으로 확인 후 전량.** 실측(MAT 84건): 생성/기존 84 · 실패 0 · 부모연결 80 · created_at 백데이트 보존. ## 한계 / 주의 - **페이지네이션**: list 계열은 1페이지(기본 100). 대량 검증은 `--format json` + 커서 추적 또는 DB 직접 카운트(`docker compose exec -e PGPASSWORD=plane plane-db psql -U plane -d plane -t -c "SELECT count(*) FROM issues;"`). - **코멘트 작성자**: API는 토큰 소유자로 기록 → 원작성자는 본문 prefix로 보존. - **삭제는 비가역**: `issues delete` 신중히. - 시크릿(API_KEY)은 `~/.env.local`에만. 이 스킬 코드(공개 repo)엔 절대 박지 않는다. ## 참고 - Plane API: https://developers.plane.so - 베이스: https://github.com/JinkoLLC/plane-skill (MIT) - 아이디어: https://github.com/cpatrickalves/plane-cli (MIT) - 서버 구성: 셀프호스트 인프라 repo 의 `plane/` 디렉토리
Ver en GitHub