원문 캡처 · github.com
원문 캡처 · github.com

claude-skills는 작업 결과를 입증하려는 엔지니어를 위한 Claude Code 스킬, 하위 에이전트, 훅 모음이다. 감독자 역할의 스킬은 각 단계를 처리할 수 있는 가장 저렴한 모델에 맡기고, 같은 작업에 두 번 실패하면 한 단계 높은 모델로 넘긴다. 각 검사 결과는 종료 코드로 판정하며, 버그 수정에는 수정 없이 새 테스트를 실행했을 때 실패한다는 증거를 붙인다. 세션이 끝날 때는 다음 세션이 이어받을 메모를 남긴다.

저장소 자체도 CI에서 메타데이터, 링크, 스크립트, 훅, README를 검사한다. 스킬 설명끼리 같은 요청을 놓고 경쟁하지 않도록 충돌 감사도 실행한다.

설치와 빠른 시작

Claude Code 안에서 플러그인으로 설치하려면 다음 명령을 실행한다.

/plugin marketplace add ehnruiz/claude-skills /plugin install agent-workflow@ehnruiz

플러그인 이름은 agent-workflow이며 ehnruiz 마켓플레이스에 등록돼 있다. 관련 이름은 .claude-plugin/에 있다. 설치하면 스킬을 /agent-workflow:handoff, /agent-workflow:pick-up처럼 네임스페이스를 붙여 호출한다. 셸에서는 다음 두 명령으로 같은 작업을 할 수 있다.

claude plugin marketplace add ehnruiz/claude-skills

claude plugin install agent-workflow@ehnruiz

설치 후 claude plugin list를 실행하면 버전과 함께 agent-workflow@ehnruiz가 표시된다.

skills CLI를 사용하면 다른 코딩 에이전트에도 설치할 수 있다. --agent 옵션으로 대상 에이전트를 지정할 수 있다.

text
npx skills add ehnruiz/claude-skills # 목록에서 선택
npx skills add ehnruiz/claude-skills --skill tdd # 스킬 하나만 설치

원하는 부분만 복사해 설치할 수도 있다.

text
git clone https://github.com/ehnruiz/claude-skills
cp -R claude-skills/skills/ticket-write ~/.claude/skills/
cp claude-skills/agents/*.md ~/.claude/agents/

요구 사항은 Claude Code이며, 스크립트와 SessionStart 훅에는 Python 3.9 이상이 필요하고 선택 사항인 훅에는 Node 20 이상이 필요하다. 무엇을 어디서 테스트했는지, 각 설치 경로를 확인하는 방법은 docs/install.md에 설명돼 있다.

플러그인을 설치한 뒤 claude plugin list에서 agent-workflow@ehnruiz가 활성화된 것을 확인할 수 있다. 스크립트 두 개는 모델 없이 실행되므로, 저장소를 복제한 상태에서 Python과 경로가 올바른지 빠르게 확인하는 데 쓸 수 있다.

text
$ python3 hooks/handoff_notice.py --print-dir /Users/you/.claude/projects/-Users-you-projects-claude-skills/handoffs $ python3 skills/skill-collision-audit/scripts/find_collisions.py skills 21 skills, 1 overlapping pairs, 0 duplicate names ...

실제 작업 흐름은 다음과 같다. 아래 슬래시 명령은 플러그인 설치를 전제로 한다. 파일을 복사해 설치했다면 agent-workflow: 접두사를 뺀다.

  • 세션을 시작하고 문제를 설명한다. 예를 들어 “날짜 파서가 2026-10-16T09:00+02:00에서 시간대를 버린다. 원인을 진단하고 수정해 달라”고 요청한다. “진단” 요청에 반응하는 diagnosing-bugs 스킬은 원인을 추측하기 전에 버그가 있을 때 실패하는 명령을 만든다. 그런 다음 문제를 재현하고, 가설의 우선순위를 매기며, 한 번에 변수 하나씩 조사한다.
  • 단계가 여러 개면 supervisor 스킬이 작업을 나눈다. 감독자는 계획과 판단을 현재 세션에 유지하고, Haiku를 사용하는 scout에 파서와 테스트를 찾게 한다. 수정 작업은 Sonnet을 사용하는 implementer에게 하나의 티켓으로 전달한다. 티켓에는 원하는 동작, 수정 위치, 검증 명령, 관련 파일, 바뀌지 않아야 할 사항이 들어간다. tdd 스킬은 구현자가 먼저 실패하는 테스트를 작성하게 한다. 작업자가 같은 티켓에서 두 번 실패하면 실패 보고서와 함께 한 단계 높은 모델로 넘긴다.
  • 검사 결과는 종료 코드로 확인한다. 감독자는 린트, 타입 검사, 테스트를 각각 별도 명령으로 실행하고 lint=0 typecheck=0 test=0처럼 보고한다. 단순히 “모두 통과했다”고만 말하지 않는다. regression-proof 스킬은 흔히 생략되는 검증도 수행한다. 병합 기준 커밋에서 만든 임시 작업 트리에 새 테스트만 복사해 실행했을 때 테스트가 실패해야 한다. docs/examples.md에는 이 저장소의 실제 수정 사례와 두 종료 코드가 나와 있다.
  • 변경 사항은 리뷰를 받는다. Opus를 사용하는 reviewer가 요청과 프로젝트 기준에 비춰 변경 사항을 검토하고, 각 지적에 파일, 줄, 실패 시나리오를 적는다. 감독자는 타당한 지적을 반영한 뒤 검사를 다시 실행한다.
  • 작업 맥락을 보존하고 세션을 끝낸다. /agent-workflow:handoff는 목표, 완료한 작업과 검증 방법, 결정 사항, 미해결 질문, 다음 단계를 담은 메모를 저장소 밖에 작성한다. 다음 세션이 시작되면 handoff_notice.py 훅이 메모의 앞부분을 보여준다. /agent-workflow:pick-up은 다음 단계에 착수하기 전에 저장소에 변화가 있었는지 확인한다.

위 흐름의 첫 두 단계에 든 요청문은 요청의 형태를 보여주는 예시일 뿐, 이 페이지를 위해 해당 요청으로 세션을 실행한 것은 아니다. 실제 실행한 것은 스크립트, 훅, 테스트, 설치 경로이며, 실행 환경은 docs/install.md에 적혀 있다.

예시와 스킬

저장소에서 실행한 세 가지 예시와 명령, 반환된 종료 코드는 docs/examples.md에 있다.

  • regression-proof를 커밋 356016b에 적용했다. 새 테스트는 부모 커밋에서 실패했고(종료 코드 1), 수정 커밋에서는 통과했다(종료 코드 0). 프로젝트는 이를 풀 리퀘스트의 테스트 계획에 포함해야 할 판정 방식으로 제시한다.
  • 저장소의 스킬 21개에 skill-collision-audit를 실행했다. 한 쌍이 점수 0.32로 표시됐지만, 두 설명이 서로를 언급하고 적용 범위를 구분해 충돌이 해결된 것으로 판단했다.
  • 문서 추가 풀 리퀘스트에서 supervisor를 실행했다. 예시에는 감독자가 직접 맡은 일과 그 이유, 각 단계의 위임 대상과 모델 등급, 리뷰 결과, 종료 코드가 있는 검사 결과가 담겼다.

스킬은 다음 작업을 지원한다.

  • supervisor는 여러 단계의 일을 티켓으로 나눠 더 저렴한 하위 에이전트에 맡긴다. 순서는 명확화, 탐색, 계획, 구현, 검증, 리뷰, 배포다. 하위 에이전트가 두 번 실패하면 한 단계 높은 모델로 올린다.
  • grilling은 계획의 결정 사항이 모두 확정될 때까지 여러 차례 질문한다. 사실은 직접 찾아보고, 사용자에게는 결정만 묻는다.
  • tdd는 한 번에 수직 기능 단위 하나씩 테스트 주도 개발을 돕는다. 좋은 테스트의 조건, 테스트 위치, 모의 객체를 쓸 때, 실패와 통과를 반복하는 절차를 다룬다.
  • diagnosing-bugs는 어려운 버그, 불안정한 테스트, 성능 저하를 다룬다. 먼저 버그가 있을 때 실패하는 명령을 만들고, 문제를 재현한 뒤 가설의 우선순위를 매기고 계측한다. 이후 테스트를 추가해 수정하고 정리한다.
  • regression-proof는 린트, 타입 검사, 테스트, 푸시 결과를 종료 코드로 판정한다. 임시 작업 트리에서 수정 없이 새 테스트가 실패하는지도 입증한다.
  • explain-the-number는 측정값을 보고하거나 변경의 성과로 제시하기 전에 비교 조건이 같은지 확인한다. 대상 집단, 측정 항목, 설정이 같고 다른 변화가 없어야 한다. 실행하지 않은 항목은 “실행하지 않음”으로 보고한다.
  • research는 백그라운드에서 researcher가 작성하는 인용 출처 포함 마크다운 메모로, 1차 자료를 바탕으로 질문에 답한다.
  • writing-for-agents는 에이전트가 매번 같은 방식으로 따르도록 스킬, AGENTS.md, CLAUDE.md를 작성하는 방법을 다룬다. 새 규칙을 배포하기 전에 새 하위 에이전트에서 실패 후 통과하는 방식으로 시험하는 방법도 설명한다.
  • handoff는 세션 끝에 목표, 완료한 작업과 검증 방법, 결정 사항, 미해결 질문, 다음 단계를 담은 인계 메모를 작성한다. 사용자가 직접 호출한다.
  • pick-up는 가장 최근 인계 메모를 불러오고 저장소에 변경 사항이 있는지 확인한 뒤 다음 단계를 시작한다.
  • no-ai-attribution는 게시 전에 커밋, 풀 리퀘스트, 이슈, 댓글, 티켓에서 AI 기여 문구와 AI 공동 저자 표시를 제거한다.
  • open-in-my-browser는 Claude in Chrome 확장 프로그램을 통해 사용자의 Chrome에서 공유한 링크를 연다. 로그인이나 VPN 뒤에 있는 페이지도 불러올 수 있다.
  • ticket-write는 글자 수 제한에 맞춰 버그, 작업, 스토리, 스파이크, 에픽 초안을 작성하고, 등록 전에 린트 스크립트로 검사한다. Jira, Linear, GitHub Issues에서 사용할 수 있다.
  • ticket-trim는 너무 긴 기존 티켓을 줄이고, 먼저 원문을 댓글에 저장한다.
  • ticket-digest는 당일 새 티켓을 티켓당 한 줄씩 정리해 채팅에 붙여 넣을 메시지로 만든다.
  • llm-integration는 언어 모델을 호출하거나 모델에 도구를 제공하는 코드의 체크리스트다. 버전 관리되는 프롬프트, 신뢰할 수 없는 입력으로 다루는 모델 출력, 비용 상한, MCP 서버의 종료 방법을 다룬다.
  • plain-writing는 메시지, 이메일, 풀 리퀘스트 설명, 댓글을 사용자의 이름으로 평이하게 작성하고 기계가 쓴 듯한 표현을 줄인다. 티켓은 ticket-write와 ticket-trim으로 넘긴다.
  • epic-review는 Jira 에픽을 범위 내 항목과 하나씩 대조하고, 리뷰 회의에서 결정할 사항을 표시하며 다음 에픽의 범위를 작성한다.
  • confluence-jira-links는 Confluence 페이지에서 각 티켓을 스마트 링크로 표시하고, 티켓이 해당 페이지로 한 번만 연결되도록 한다.
  • leader-1-1-prep는 상위 관리자와의 일대일 면담을 위한 한 화면 분량의 요약을 만든다. 이어받은 일, 최대 두 가지 요청, 사람과 전략, 성장에 관한 질문 하나를 담는다.
  • skill-collision-audit는 같은 요청을 두고 경쟁하는 스킬 설명을 찾아 요청마다 정확히 하나의 스킬이 선택되도록 설명을 수정한다. 스크립트는 겹치는 설명 쌍과 이름이 중복된 스킬을 추리고, Claude가 현실적인 요청을 기준으로 각 쌍을 판단한다.

티켓 제한과 충돌 검사

skills/ticket-write/scripts/ticket_lint.py는 초안이 아래 제한을 지키는지 검사하고, 기술 메모로 옮겨야 할 식별자를 표시한다.

  • 제목: 최대 80자
  • 설명: 버그, 작업, 스토리는 최대 150단어. 스파이크와 에픽은 최대 80단어
  • 승인 기준: 불릿 2~5개
  • 설명 안의 코드 식별자: 최대 3개
  • 기술 메모 댓글: 최대 250단어

다음은 버그 티켓 검사 예시다.

text
$ python3 ticket_lint.py --type bug --title "Product pages lose search data" draft.md ok    title characters: 30 (limit 80) ok    description words: 36 (limit 150) ok    headings: 3 (limit 6) ok    code identifiers: 0 (limit 3) ok    acceptance criteria: 2 (limit 2-5)

skills/skill-collision-audit/scripts/find_collisions.py는 스킬 설명 두 개씩을 비교해 서로 공유하는 특징적인 단어를 기준으로 점수를 매긴다.

text
$ python3 find_collisions.py ~/.claude/skills .claude/skills 55 skills, 14 overlapping pairs, 0 duplicate names 0.73  built-in-browser  <->  chrome-browser       shared: browser, tool, mcp, chrome, own, before

높은 점수는 살펴볼 이유일 뿐, 충돌 판정 자체는 아니다. 위 예시의 두 스킬은 각 설명에서 어떤 브라우저를 대상으로 하는지 이미 구분한다. 실제 충돌이 있는지는 스킬이 현실적인 요청을 각 쌍에 적용해 판단하고, 필요한 설명만 고친다.

하위 에이전트와 훅

각 하위 에이전트의 모델은 해당 파일에 지정돼 있으며, supervisor 스킬이 작업을 맡긴다.

  • scout은 Haiku를 사용해 정보를 찾고 파일:줄 위치를 반환한다. 파일은 수정하지 않는다.
  • doc-writer은 Haiku를 사용해 주어진 사실을 바탕으로 글을 쓴다. 사실이 빠진 곳에는 TODO(fact)라고 적는다.
  • implementer은 Sonnet을 사용해 티켓 하나를 테스트 우선 방식으로 구현하고 각 명령의 종료 코드를 보고한다. 커밋은 하지 않는다.
  • tester은 Sonnet을 사용해 테스트를 작성하고 실행하며, 테스트와 픽스처만 수정한다.
  • researcher은 Sonnet을 사용해 백그라운드에서 1차 자료를 읽고, 모든 주장에 출처와 날짜를 붙인 메모를 작성한다.
  • reviewer은 Opus를 사용해 티켓과 저장소 기준에 따라 변경 사항을 검토하고 각 지적에 실패 시나리오를 제시한다.

handoff_notice.py는 SessionStart 이벤트에서 프로젝트의 가장 최근 인계 메모 앞부분을 보여주고 pick-up을 안내한다. 메모가 없거나 저장소 자체에 handoff 스킬이 있으면 조용히 동작한다.

나머지 네 훅은 선택 사항이며 기본 플러그인에 등록되지 않는다.

  • config-protection.mjs는 PreToolUse에서 기존 린트, 타입 검사, 테스트, 빌드, CI 설정 파일의 편집을 차단한다.
  • commit-secrets.mjs는 PreToolUse에서 git commit에 포함될 내용을 검사하고 비밀 정보를 찾으면 거부하거나 사용자에게 확인을 요청한다.
  • edited-files.mjs는 PostToolUse에서 세션이 수정한 파일을 기록해 stop-check.mjs가 사용할 수 있게 한다.
  • stop-check.mjs는 Stop 이벤트에서 응답이 끝나기 전에 수정한 파일에 eslint와 타입 검사를 실행한다.

플러그인은 hooks/hooks.json을 통해 handoff_notice.py를 등록한다. 선택 사항인 네 훅은 등록하지 않는다. 이를 설정하는 예시는 hooks/README.md에 있다. 파일을 복사해 설치했다면 handoff_notice.py를 ~/.claude/settings.json에 추가한다.

json
{
 "hooks": {
 "SessionStart": [
 { "matcher": "startup|clear|compact",
 "hooks": [{ "type": "command", "command": "python3 /path/to/claude-skills/hooks/handoff_notice.py", "timeout": 10 }] }
 ]
 }
}

세션 규칙과 개인 설정

세션 중 특정 순간에 필요한 습관은 요청에 반응하는 스킬 설명만으로 작동하지 않을 수 있다. 이런 규칙은 ~/.claude/CLAUDE.md에 넣는다.

데스크톱 앱에서 응답을 기다리는 세션을 분류하려면 사이드바에 Pending my feedback이라는 섹션을 만든 뒤 다음 규칙을 추가한다.

text
Whenever a session ends its turn waiting on my answer, decision or approval, move it into the sidebar
section named "Pending my feedback" (`mcp__ccd_sidebar__move_sessions` with `session_ids: ["self"]` and the
section's id from `mcp__ccd_sidebar__list_sections`; load the tools with ToolSearch first if they are
deferred). Once I have answered and the work resumes, move it back to Ungrouped (`section_id: "sessions"`)
or to the section it came from. Sessions outside the desktop app skip this.

~/.claude/skills/의 스킬은 같은 이름을 가진 프로젝트의 .claude/skills/ 스킬보다 우선한다. 따라서 supervisor, handoff, pick-up, tdd, diagnosing-bugs는 먼저 프로젝트에 같은 이름의 스킬이 있는지 확인하고, 있으면 그 스킬을 따른다. 하위 에이전트에는 이런 절차가 필요 없다. 프로젝트의 .claude/agents/ 파일이 이 저장소에서 설치한 파일보다 우선하기 때문이다.

개발과 배포

테스트는 다음 명령으로 실행한다.

text
python3 -m unittest discover -s tests -v
node --test tests/hooks/
claude plugin validate .

Node 테스트는 선택 사항인 훅 네 개를 검사한다. Python 테스트는 린트 스크립트, 충돌 검사 스크립트, 인계 훅, 각 스킬과 하위 에이전트의 프런트매터, 스킬과 문서 안의 링크를 확인한다. README에 모든 스킬과 하위 에이전트가 나열됐는지, 플러그인 이름이 매니페스트와 일치하는지, 변경 기록에 현재 버전 항목이 있는지도 검사한다. CI는 지원하는 가장 오래된 런타임과 현재 런타임에서 두 테스트 모음을 모두 실행한다. Python은 3.9와 3.12, Node는 20과 22를 사용한다.

버전별 변경 사항은 CHANGELOG.md에 있다. 버전을 올리는 시점, 릴리스 태그를 만드는 방법, 설치된 사용자에게 릴리스를 전달하는 방법은 docs/releasing.md에 설명돼 있다.

출처와 라이선스

인계 스킬은 Matt Pocock의 skills에 있는 인계 아이디어에서 발전했다. grilling, tdd, diagnosing-bugs, research, writing-for-agents는 같은 저장소의 내용을 MIT 라이선스에 따라 적용했으며, 각각의 LICENSE.md에 고지 사항을 유지한다.

explain-the-number는 Lauren Tan의 pstack에 있는 같은 이름의 원칙을 따른다. MIT 라이선스에 따라 자체 LICENSE.md에 고지 사항을 유지한다. writing-for-agents/PRESSURE-TESTS.md는 obra/clank의 testing-skills-with-subagents 방법을 다시 쓴 것이다. 해당 저장소에는 라이선스 파일이 없어 문구를 복사하지 않았다.

라이선스는 MIT다.