Claude Code 워크플로우 스킬을 한국어로 옮긴 포크, suberpower
번역이 지시의 힘을 약화하지 않도록
2026/09/04Claude Code 워크플로우 스킬을 한국어로 옮긴 포크, suberpower
Claude Code를 사용하며 superpowers라는 플러그인을 알게 됐다. 브레인스토밍, 계획 작성, TDD, 디버깅, 코드 리뷰 등 개발 과정 전반을 스킬로 묶어두고, Claude가 현재 작업 성격에 맞는 스킬을 스스로 찾아 실행하도록 유도하는 도구다. claude-sync를 개발할 때 적용했던 'Spec → Plan → TDD' 흐름도 이 스킬들을 활용해 진행했다.
이 플러그인을 직접 포크(Fork)한 이유는 두 가지다.
첫째는 공부다. superpowers는 프롬프트 엔지니어링 관점에서 잘 짜여진 워크플로우 하네스(Harness)다. 스킬을 어떤 단위로 나누는지, Claude에게 어느 정도의 강도로 지시를 내리는지, 서브 에이전트와는 컨텍스트를 어떻게 주고받는지 직접 뜯어보며 배우고 싶었다. 그래서 한 문장씩 한국어로 번역하며 구조를 분석했다.
둘째는 내 작업 방식에 맞게 커스텀하기 위해서다. 원본을 그대로 쓰다 보니 Git worktree를 다루는 방식 등 내 워크플로우와 맞지 않는 부분들이 있었고, 사용 중 마주친 버그들을 직접 수정하고 싶었다.
이름은 suberpower
원본과 헷갈리지 않도록 이름을 살짝 비틀어 지었다. 두 플러그인을 동시에 활성화하면 세션 시작 시 스킬 안내가 두 번 주입되는데, 이름까지 같으면 어느 쪽 스킬이 로드되었는지 디버깅하기 어렵기 때문이다. 스킬을 호출하는 네임스페이스 역시 suberpower:brainstorming처럼 원본과 분리했다.
번역에서 지킨 원칙
일반 문장만 번역한다
본문의 설명은 한국어로 옮기되, 제목(## Overview), 기술 용어(skill, subagent, commit), 상태값(DONE, BLOCKED)은 영문 그대로 유지했다. 영문 뒤에는 dispatch하고, commit하세요처럼 조사를 바로 붙여 가독성을 챙겼다.
원본의 강조 강도를 보존한다
번역 과정에서 가장 신경 쓴 부분이다. 영문 프롬프트는 주로 대문자(Capitalization)를 통해 지시의 강도를 표현한다. 하지만 한국어에는 대소문자 구분이 없으므로 이를 평범한 문장으로 직역하면 최상위 경고가 일반적인 권고 수준으로 희석되고, 결과적으로 LLM에 대한 지시 구속력이 약해진다.
처음에는 CRITICAL:을 중요:로 번역해 보았으나, 서브 에이전트가 해당 지시를 잘 따르지 않아 다시 롤백했다. 이후로는 원문의 강조 등급을 서식으로 매핑하여 강도를 살렸다.
| 원문의 강도 | 번역 시 적용 방식 | 예시 |
|---|---|---|
| 최상위 | 영문 대문자 토큰 유지 | IMPORTANT:, CRITICAL: |
| 상위 | 영문 라벨 + 대시 | STOP - 다음 경우 escalate하세요 |
| 중간 | 볼드체 적용 | **반드시**, **절대** |
| 하위 | 일반 평문 |
예를 들어, 스킬 사용 규칙의 핵심 프롬프트는 아래와 같이 번역했다. 태그는 원문 그대로 유지하고, ABSOLUTELY MUST는 의미가 희석되지 않도록 "반드시"로 옮겼다.
<!-- 원문 -->
<EXTREMELY-IMPORTANT>
If you think there is even a 1% chance a skill might apply to what you are doing, you ABSOLUTELY MUST invoke the skill.
</EXTREMELY-IMPORTANT>
<!-- suberpower -->
<EXTREMELY-IMPORTANT>
지금 하고 있는 일에 어떤 skill이 적용될 가능성이 1%라도 있다고 생각된다면, 반드시 그 skill을 호출해야 합니다.
</EXTREMELY-IMPORTANT>
포크해서 얻은 이점
직접 포크를 유지하며 얻은 가장 큰 장점은 작업 흐름을 방해하는 요소를 업스트림 반영까지 기다리지 않고 즉시 수정할 수 있다는 것이다. 효과가 컸던 두 가지 사례를 소개한다.
Worktree: 작업 공간을 프로젝트 밖으로 분리
원본의 worktree 스킬은 Claude Code에 내장된 worktree 생성 기능에 의존한다. 하지만 이 방식은 내 작업 스타일과 세 가지 면에서 맞지 않았다.
.claude/worktrees/디렉터리 하위(프로젝트 내부)에 생성된다. 이로 인해.gitignore설정에 따라 원래 저장소의git status에 추적되지 않은(untracked) 파일로 잡힐 수 있다.- 기준 브랜치가 설정값에 묶여 있어, 사실상
main브랜치에 고정된 것처럼 동작한다. - 브랜치명을 지정하지 않으면
worktree-xxxx같은 무작위 이름이 부여된다.
그래서 내장 기능에 의존하는 대신, 스킬이 Git 명령어를 통해 worktree를 직접 구성하도록 로직을 재작성했다. 흐름은 다음과 같다.
- 이미 worktree 내부에서 작업 중이라면 새로 만들지 않는다.
- 분기할 기준 브랜치를 묻는다. 프로젝트당 한 번만 물어보고 기억해 둔다.
- 생성할 브랜치 이름을 묻는다.
- 프로젝트 외부의 전역 경로에 worktree를 생성한다.
project=$(basename "$(git rev-parse --show-toplevel)")
path="$HOME/.claude/suberpowers/worktrees/$project/$BRANCH_NAME"
git worktree add "$path" -b "$BRANCH_NAME" "$BASE_REF"
이렇게 개선한 후 얻은 이점은 명확했다.
- 작업 저장소가 오염되지 않는다. worktree가 프로젝트 디렉터리 밖에 있으므로
git status에 잡힐 일이 없고, 이를 무시하기 위해.gitignore를 수정할 필요도 없다. - 원하는 브랜치에서 분기할 수 있다.
develop등main이 아닌 브랜치를 기준으로 작업하는 프로젝트에서도 유연하게 대응할 수 있다. - 컨텍스트 파악이 쉽다.
fix-login처럼 목적이 뚜렷한 브랜치명을 사용하므로 나중에 작업 목록을 볼 때 헷갈리지 않는다.
다만 잃은 것도 있다. 기존 내장 기능은 세션 종료 시 worktree 삭제 여부를 물어보지만, Git으로 직접 만든 worktree는 Claude Code가 생명 주기를 추적하지 않아 해당 프롬프트가 뜨지 않는다. 이 부분은 작업을 최종 마무리하는 별도의 스킬이 처리하도록 역할을 위임했다.
리뷰어 응답 실패(Silent Failure) 버그 개선
코드 작성이 끝나면 리뷰 서브 에이전트가 결과를 검토한다. 그런데 리뷰 에이전트가 아무런 결과도 반환하지 못한 채 조용히 종료되는 현상이 잦았다. 에러를 뱉으며 죽으면 그나마 다행인데, 아무 통지 없이 연결이 끊기면 메인 세션은 오지 않을 결과를 하염없이 기다리는 상태(Hang)에 빠졌다.
원인은 Claude Code 측의 알려진 버그(#75318)였다. 에이전트가 긴 시간 동안 조용히 추론만 하다가 방대한 양의 텍스트를 한 번에 스트리밍하려 할 때 연결이 끊기면, 메인 세션은 자동으로 복구되지만 서브 에이전트 프로세스는 그대로 죽어버리는 문제였다. 변경된 diff를 꼼꼼히 읽고 긴 리뷰 보고서를 한 번에 작성해야 하는 리뷰 에이전트가 딱 이 케이스에 해당됐다.
공식 버그가 수정되기를 마냥 기다릴 수 없어, 리뷰어와의 상호작용 방식을 바꿨다.
- 결과를 파일에 점진적으로 기록한다. 리뷰어는 시작 직후 보고서 파일을 생성하고, 지적 사항이 하나 확정될 때마다 파일에 즉시 쓴다. 메인 세션으로 반환하는 최종 응답은 '파일 경로, 최종 판정, 이슈 개수' 세 줄로 최소화한다.
- 끊기면 이어서 재개한다. 리뷰어가 결과 없이 비정상 종료되면 메인 세션이 먼저 보고서 파일을 읽는다. 완료된 상태라면 그대로 진행하고, 미완성이라면 새 리뷰어를 띄워 "기록된 항목은 건너뛰고 남은 범위만 이어서 검토하라"고 지시한다. (무한 루프 방지를 위해 재시도는 최대 2회로 제한했다.)
- 큰 변경 사항은 분할 정복(Divide & Conquer)한다. 변경된 코드가 500줄을 넘거나 파일이 8개를 넘으면, 연관된 파일끼리 묶어 여러 명의 리뷰 에이전트를 동시에 띄운다.
이러한 우회 기법(Workaround)을 통해 다음과 같은 이점을 얻었다.
- 연결 끊김 조건 회피: 방대한 응답을 한 번에 내보내는 순간이 사라졌다.
- 데이터 유실 방지: 도중에 끊겨도 파일에 기록된 중간 결과물은 안전하게 보존된다.
- 복구 비용 최소화: 실패 시 처음부터 다시 검토하지 않고 남은 부분만 이어서 처리한다.
- 리뷰 품질 향상: 검토할 코드 범위를 나누어 주면, 단일 에이전트가 감당해야 할 컨텍스트가 줄어들어 리뷰 품질에도 이롭고 도중에 실패할 확률도 낮아진다.
참고로 리뷰 보고서 파일 역시 worktree와 동일한 이유로 프로젝트 외부 경로(~/.claude/suberpowers/reviews/)에 저장한다. 프로젝트 내부에 쓰면 에이전트가 이를 "사용자가 요청하지 않은 추가 파일 생성"으로 오인하여 혼란을 겪을 수 있기 때문이다. 여러 에이전트가 나누어 리뷰할 경우 파일 간의 연관성(Cross-file) 이슈를 놓칠 수 있는데, 이는 메인 세션이 분할된 보고서들을 취합하여 최종 판정할 때 한 번 더 짚어보도록 보완했다.
마지막으로, 이러한 우회 코드는 원인 버그가 수정되면 걷어내야 하는 기술 부채다. 따라서 코드 베이스에 우회책을 적용할 때마다 관련된 Claude Code 이슈 번호를 명시하고, GitHub Actions를 통해 매주 해당 이슈의 Close 여부를 트래킹하도록 설정했다. 이슈가 해결되면 "이제 이 우회책을 제거할지 검토하라"는 알림성 이슈가 내 저장소에 자동으로 생성된다.
업스트림(원본)과의 동기화 유지하기
포크를 유지할 때 가장 까다로운 부분은 **원본 저장소의 업데이트를 가져올 때(Sync)**다. 원본의 변경 사항을 단순 병합하다 보면, 내가 의도적으로 수정한 규칙(worktree 로직, 번역 톤 등)이 조용히 덮어씌워져 유실되기 쉽다.
이를 방지하기 위해 "의도적으로 원본과 다르게 유지하는 지점"을 문서화해 두었다. 현재 이름 변경, worktree 재작성, 번역 규칙, 강조 계층 등 총 7개의 항목이 있으며, 각 항목마다 원본 업데이트 시의 병합 정책을 명시했다.
- 절대 덮어쓰지 않음: 플러그인 이름처럼 포크의 정체성을 결정하는 요소
- 선별 반영: worktree 스킬처럼 로직 전체를 뜯어고친 부분
- 형식 변환 후 수용: 스킬 설명(description)처럼 내용만 내 번역 규칙에 맞게 가공하여 가져오는 부분
이 정책들이 잘 지켜지는지 확인하기 위해 검사 스크립트를 작성했다. 문자열 매칭이나 파일 경로 등 기계적인 검증이 가능한 부분은 스크립트가 자동 판정한다. 반면 번역의 어투나 문맥처럼 직접 읽어봐야 하는 항목은 스크립트가 체크리스트 형태의 프롬프트를 띄우고, 작업자가 수동으로 확인(Acknowledge)하기 전에는 검사를 통과시키지 않는다.
./scripts/check-divergence.sh # 일반적인 로컬 무결성 검사
./scripts/check-divergence.sh --sync # 업스트림 동기화 시, 작업자의 수동 확인 프로세스 포함
기계적으로 검증하기 어려운 항목일수록 업데이트 과정에서 유실되기 쉬운데, 이처럼 강제 확인 절차를 두어 최소한 검토 없이 덮어써지는 사고를 막을 수 있게 했다.
설치 방법
claude plugin marketplace add june20516/suberpower
claude plugin install suberpower@suberpower
원본 superpowers 플러그인과 동시에 활성화하면 세션 시작 안내가 중복 출력되므로, 둘 중 하나만 사용하는 것을 권장한다.
마무리
초기에는 단순히 단어를 한국어로 치환하는 작업이라 생각했지만, 실제로는 LLM을 통제하는 **'지시의 강도를 번역하는 일'**에 가까웠다. 한 문장씩 곱씹으며 프롬프트의 의도를 분석한 덕분에, 플러그인 사용 중 불편한 점이 생겼을 때 아키텍처의 어느 부분을 수정해야 할지 명확히 파악할 수 있는 시야를 얻었다.
설치 명령어와 저장소 링크는 Lab의 Claude Tools 페이지에 정리해 두었고, 전체 소스 코드는 GitHub 저장소에서 확인할 수 있다.