Claude Code의 plan 모드 출력을 트리 구조의 설계서로 변환하고, 구현 후 코드와의 일치 여부를 검증하여 그대로 PR(Pull Request) 본문에 삽입하는 CLI 도구인 cc-plan-tree를 만들었습니다.
cc-plan-tree demo
uv tool install cc-plan-tree && cc-plan-tree init
과제: plan 모드의 설계 판단은 사라진다
Claude Code의 plan 모드는 편리하지만, 출력은 긴 텍스트입니다. 그리고 가장 아까운 점은, 플랜 중의 설계 판단이 남지 않는다는 것입니다.
예를 들어 plan 모드 중에 Claude가 "리프레시 토큰(Refresh Token)의 저장 위치는 HttpOnly 쿠키와 localStorage 중 어느 것으로 하시겠습니까?"라고 물었고, 당신이 "쿠키(XSS 대책)"라고 대답했다고 가정해 봅시다. 이 "localStorage를 검토했으나, XSS 리스크를 이유로 기각했다"라는 정보는 세션이 끝나면 사라집니다. 몇 달 후 코드 리뷰에서 "왜 localStorage가 아닌가요?"라는 질문을 받아도 기록은 어디에도 없습니다.
만든 것
cc-plan-tree는 Claude Code에 3가지 슬래시 명령어(Slash Command)를 추가합니다.
| 명령어 | 역할 |
|---|
/plan-tree <태스크> | 플랜을 트리 구조의 JSON으로 기록. Claude의 질문은 결정 노드(Decision Node)가 되며, 채택한 선택지와 기각한 선택지(기각 이유 포함)가 모두 남음. 플랜 제시 시 인터랙티브(Interactive)한 HTML 트리가 브라우저에서 열림 |
/plan-verify | 구현 후, 설계 트리와 git diff를 대조하여 "일치 / 괴리 / 미구현"을 노드 단위로 보고. 괴리가 있다면 "코드를 수정할지, 트리를 수정할지"를 선택하여 해소. 마지막에 PR 본문으로 설계 트리를 삽입 |
/plan-export | 설계 트리를 PNG 이미지로 내보내기 (문서나 Slack용) |
포인트는 /plan-verify의 마지막 단계입니다.
GitHub는 PR 본문의 Mermaid 코드 블록을 네이티브하게 도표로 렌더링하기 때문에, 이미지 업로드 없이도 리뷰어가 설계의 전체 모습과 "채택하지 않은 선택지"를 도표로 볼 수 있습니다.
실제 PR에서의 모습은 여기에서 확인할 수 있습니다: https://github.com/natsu0529/cc-plan-tree/pull/1
기술적인 고안
헤드리스 브라우저를 사용하지 않는 PNG 생성
Mermaid 도표의 PNG화에는 통상적으로 mermaid-cli(내부에서 puppeteer=Chromium이 동작)를 사용하지만, pip install 한 번으로 동작하는 도구로 만들고 싶었기에 채택하지 않았습니다. 플랜의 데이터 구조는 자체 포맷이므로, 트리의 레이아웃 계산을 직접 구현하여 Pillow로 직접 그립니다. 의존성은 Pillow 단 하나뿐입니다.
일본어 라벨도 고려하여, 레이아웃 계산 시 CJK 문자를 반각 2글자 너비로 추정하고, 줄바꿈은 영어 단어 중간에서 끊기지 않도록 했습니다.
인터랙티브 HTML도 단일 파일·의존성 제로
/plan-tree가 브라우저에서 여는 트리는 CSS/JS를 모두 인라인화한 단일 HTML입니다. 노드 클릭으로 가지를 접을 수 있고, 기각 옵션에 호버(Hover)하면 기각 이유가 툴팁(Tooltip)으로 나타납니다. 트리의 렌더링은 flexbox와 의사 요소(Pseudo-element)만으로 구현하여 외부 라이브러리는 전혀 사용하지 않았습니다.
여기서 한 가지 함정에 빠졌습니다. justify-content: center로 트리를 중앙 정렬하면, 콘텐츠가 컨테이너보다 넓을 때 왼쪽 부분이 스크롤 불가능한 화면 밖으로 밀려납니다(flexbox의 유명한 함정). 이를 width: max-content; margin: 0 auto로 교체하여 해결했습니다.
슬래시 명령어의 "오래된 복사본" 문제
슬래시 명령어의 실체는 ~/.claude/commands/에 복사되는 markdown이므로, 패키지를 업데이트해도 이미 전개된 명령어는 옛날 상태 그대로입니다. 직접 도그푸딩(Dogfooding)을 하던 중 이 문제를 겪었기에, init이 전개하는 md에 버전 마커를 삽입하여 CLI 실행 시 불일치가 감지되면 경고를 띄우도록 했습니다.
릴리스는 Trusted Publishing
PyPI 공개는 GitHub Actions의 OIDC (Trusted Publishing)를 사용했으므로, API 토큰의 발행 및 보관이 전혀 필요하지 않습니다. git tag v0.2.0 && git push --tags 명령만으로 릴리스가 실행됩니다.
사용법
uv tool install cc-plan-tree # 또는 pip install cc-plan-tree
cc-plan-tree init # 슬래시 커맨드(slash command)를 ~/.claude/commands 에 전개
그 후 Claude Code에서
/plan-tree 로그인 API에 속도 제한(rate limit) 추가
와 같이 사용하기만 하면 됩니다.
향후 계획
- 다른 코딩 에이전트 (Codex CLI / Gemini CLI)용 어댑터 — 플랜의 JSON 포맷은 에이전트에 의존하지 않도록 설계되어 있으므로, 어댑터 추가는 컨트리뷰션(contribution)의 입구로서 최적입니다.
- 플랜의 버전 간 diff ("당초 설계"와 "실제 출하된 것"의 차이 가시화)
피드백 및 PR을 환영합니다!
Discussion