disk-cleaner 프로젝트를 Skill에서 Plugin으로 전환하면서 배운 설계 원칙을 정리한다.
Skill vs Plugin, 언제 무엇을 선택하나
Claude Code에서 기능을 패키징하는 방식은 크게 두 가지다:
| 타입 | 트리거 | 역할 | 예시 |
|---|---|---|---|
| Type B: Skill | Claude가 대화 맥락에 따라 자동 적용 | "어떻게 할지" — 도메인 지식 | 코드 리뷰 가이드라인 |
| Type A: Plugin | 사용자가 /command로 직접 호출 |
"무엇을 할지" — 액션 진입점 | /disk-cleaner:clean |
선택 기준은 단순하다: 사용자가 명시적으로 실행해야 하면 Plugin, Claude가 알아서 참고하면 되면 Skill.
disk-cleaner는 "디스크 정리해줘"라고 할 때 스크립트를 실행해야 하므로 Plugin이 맞다. Skill로 만들면 slash command가 없어서 사용자가 직접 호출할 수 없다.
Command + Skill 분리 패턴
Plugin의 핵심은 Command와 Skill의 분리다:
commands/clean.md → "무엇을 할지" (스크립트 실행, 결과 요약)
skills/disk-cleaner/ → "어떻게 할지" (cleaner 목록, 안전 장치, 설정)
Command는 가볍게 — 실행 방법과 결과 안내만 담는다. Skill은 Claude가 Command 실행 시 자동으로 참조하는 배경 지식이다. 이 분리 덕분에:
- Command를 읽는 비용이 낮아진다 (프롬프트 토큰 절약)
- Skill은 대화 맥락에서도 자동 활성화된다
- 각각 독립적으로 업데이트할 수 있다
표준 디렉토리 구조
plugin-name/
├── .claude-plugin/
│ └── plugin.json # 플러그인 매니페스트
├── commands/
│ └── clean.md # /plugin:command 진입점
├── skills/
│ └── domain-knowledge/
│ └── SKILL.md # 자동 참조 도메인 지식
├── scripts/ # 실행 로직 통일
├── config/ # 설정 파일
├── output/ # 생성물 (.gitignore)
└── README.md
배치 원칙: 소속 범위로 결정한다.
- 하나의 skill에서만 쓰면 →
skills/해당-skill/내부 - 여러 구성 요소가 공유하면 → 플러그인 루트
- 실행 로직은 항상 →
scripts/
마이그레이션 실전 기록
Before (Type B: Skill)
disk-cleaner/
├── SKILL.md # 루트에 단일 파일
├── disk-cleaner # 실행 스크립트 (루트)
├── install.sh # 루트
└── disk-cleaner.conf.example # 루트
After (Type A: Plugin)
disk-cleaner/
├── .claude-plugin/plugin.json # 매니페스트 추가
├── commands/clean.md # Command 분리
├── skills/disk-cleaner/SKILL.md # Skill 분리
├── scripts/disk-cleaner # scripts/로 이동
├── scripts/install.sh # scripts/로 이동
├── config/disk-cleaner.conf.example
└── output/REPORT-*.md # .gitignore
마이그레이션 체크리스트
.claude-plugin/plugin.json생성 (name, version, description)- SKILL.md를 Command + Skill로 분리
- 실행 스크립트를
scripts/로 이동 - 설정 파일을
config/로 이동 - 생성물을
output/으로 이동 +.gitignore settings.json→settings.local.json으로 통합- 내부 경로 참조 업데이트 (install.sh, SKILL.md, README.md)
- 로컬 마켓플레이스에 등록
로컬 마켓플레이스로 전역 사용
Plugin을 만들면 해당 디렉토리에서만 인식된다. 다른 프로젝트에서도 쓰려면 로컬 마켓플레이스에 등록:
// ~/elon/ai/projects/.claude-plugin/marketplace.json
{
"plugins": [
{
"name": "disk-cleaner",
"source": "./disk-cleaner",
"version": "1.0.0"
}
]
}
등록 후 Claude Code 재시작 → /plugin → install. 이제 어떤 프로젝트에서든 /disk-cleaner:clean으로 호출 가능.
핵심 교훈
- Skill과 Plugin은 용도가 다르다 — "자동 참조"와 "명시적 실행"의 차이
- Command는 가볍게, Skill은 풍부하게 — 분리하면 토큰도 절약되고 유지보수도 쉽다
- 디렉토리 구조는 컨벤션을 따르라 —
scripts/,config/,output/같은 표준 위치가 있으면 고민할 필요 없다 - 마켓플레이스 등록은 간단하다 — JSON 한 줄이면 전역 사용 가능