CH 23 · 발행과 배포
본 장 목표
PART 04를 진행하면서 플러그인 설치와 플러그인 작성법을 배웠습니다 — 그러나 그것은 아직 본인 워크스페이스의 폴더 안에 머물러 있을 뿐이며, 다른 사람은 어떻게 그것을 얻을 수 있을까요? 이 장에서는 "한 줄 명령으로 설치"하는 배포 형태로 바꾸는 방법을 다룹니다: 먼저 다른 사람이 본인의 플러그인을 설치하는 메커니즘(bundle 패키지)을 설명하고, 이어서 세 가지 배포 방법을 제시하며, 마지막으로 발행 전에 스스로 설치해 검증해, 문제가 없음을 확인한 뒤 발행하도록 합니다.
먼저 분명히 하기: 다른 사람은 어떻게 본인의 플러그인을 설치하는가
dsh에는 내장 플러그인 마켓이 없으며, 공식 설치는 통일되게 dsh plugin --profile <이름> add <출처>를 거칩니다. 출처는 네 가지입니다: npm 패키지명 / 로컬 디렉터리 / tarball / GitHub Release(CH 17에서 체계적으로 다룸). 따라서 본인이 해야 할 일은 플러그인을 이 네 가지 출처 중 하나로 만들어 내는 것입니다.
"다른 사람이 add할 수 있는 플러그인"은 dsh에서 공식 명칭이 있습니다 — bundle (패키지). 두 개념을 혼동하지 마세요:
- bundle은 본인이 작성해 배포하는 것입니다. 그 package.json은
dsh.bundle을 선언하며, "이 패키지가 무엇을 기여하는가" — 플러그인 라인을 삽입하거나 재정의하는 패치 파일 — 에 답합니다. - profile은 사용자가
dsh --profile <이름>으로 시작하는 것입니다. 그 package.json은dsh.profile을 선언하며, "어떤 bundle이 어떤 순서로 이 설정을 구성하는가"에 답합니다.
둘 다인 것은 없습니다. 본인이 bundle을 배포하고, 사용자는 그것을 profile로 설치해 실행합니다.
발행 가능한 플러그인의 형태
작성 완료된 플러그인 디렉터리 안에서, 가장 중요한 세 가지:
your-plugin/
├── package.json # dsh.bundle 선언 (UI가 있다면 dsh.client도)
├── cordis.patch.yml # 설치 시 적용되는 패치 레이어
└── lib/ # 빌드 산출물 — 다른 사람이 실제로 설치하는 것package.json의 이 필드들은 하나도 소홀히 해선 안 됩니다:
| 필드 | 설명 |
|---|---|
name | 패키지명, 플러그인과 일치, 읽기 좋게 |
version | 시맨틱 버전, major.minor.patch, 0.0.1부터 시작 |
description | 플러그인이 무엇을 하는지 한 줄 설명, 설치 목록에 표시 |
type | module (ESM) |
main | 빌드 산출물 지정, 예: lib/index.js |
files | 배송에 필요한 것만 묶음: lib, cordis.patch.yml, LICENSE 등. lib이 빠지면 다른 사람이 설치 후 적재에 실패 |
keywords | 검색 키워드, ["deepseek","harness","dsh","dsh-plugin",...] — dsh-plugin은 검색에서 발견되기 위한 표준 |
license | 오픈소스는 반드시 선언, 예: MIT |
dsh.bundle | {"patch":"./cordis.patch.yml"} — 패키지임을 선언, 설치 시 자동 마운트 |
dsh.client | UI가 있는 플러그인은 client 주입을 선언(CH 22에서 다룬 범주) |
세 가지 배포 방법
가벼운 것부터 무거운 순서로. 첫 번째는 순수 로컬 자체 검증이며 계정이 필요 없고, 나머지 둘은 계정이 필요합니다 — GitHub는 GitHub 계정, npm은 npm 계정이 필요합니다.
방법 1: 로컬 디렉터리 / tarball — 발행 전 자체 검증
- 로컬 디렉터리:
dsh plugin --profile demo add ./your-plugin, pnpm이 해당 디렉터리를 직접 링크, 개발 중 빠른 시도에 적합. - tarball: 플러그인 디렉터리에서
pnpm pack으로.tgz를 만든 뒤,dsh plugin --profile demo add ./your-plugin-0.0.1.tgz.
발행 전에는 반드시 tarball로 직접 설치해 검증하세요 — tarball는 그대로 배송할 것과 동일합니다. 설치되고 실행된다면, 발행해도 좋다고 판단할 수 있습니다. 자체 검증은 세 단계로 완료합니다:
# 플러그인 디렉터리에서 패키징
pnpm pack
# 깨끗한 임시 profile에 설치
dsh plugin --profile test add ./your-plugin-0.0.1.tgz
# 설정 트리에 들어갔는지 확인
dsh --profile test --dump-config--dump-config 출력에서 본인의 플러그인 레이어가 보이면 패키지가 정상적으로 적재된 것입니다. 이어서 dsh --profile test로 시작해 플러그인의 기능이 정상 작동하는지 테스트하고, 모두 정상이라면 발행합니다.
두 가지 디테일을 기억하세요:
- bundle 멤버의 변경 이후에는 반드시 profile을 재시작해야 적용됩니다 — 실행 중인 profile은 시작 시점의 bundle 집합을 그대로 유지합니다(CH 17의 경계), 설치 후 재시작하고 나서 테스트합니다.
- 적재 순서: profile의 bundles 목록 → profile 자체 cordis.patch.yml →
$DSH_HOME/cordis.patch.yml→--patch오버레이, 나중에 적용된 라인이 이깁니다. 본인의 플러그인은 첫 번째 레이어에 속합니다.
dsh에게 맡길 수도 있습니다. 다음 메시지를 dsh에게 보내면, 문서 읽기, 패키징, 임시 profile 설치, 확인을 해주며, 그저 검증하시면 됩니다.
현재 워크스페이스의 플러그인을 발행 가능한 형태로 패키징하고, 발행 전 자체 검증을 수행해 줘: 먼저 dsh 공식 문서를 읽어 플러그인을 어떻게 패키징하고 설치하는지(번들 패키지, dsh plugin add의 네 가지 출처) 파악한 다음, 공식 명세에 따라 진행해; 플러그인을 tarball로 패키징하고, package.json 메타데이터(version, description, files, keywords, license)가 완전한지 확인해; 임시 profile에 설치해 적재되고 기능이 정상 작동하는지 검증해; 마지막에 검증 결과와 패키징된 산출물의 경로를 알려 주고, npm에 발행하기 위해 내가 추가로 무엇을 해야 하는지 설명해 줘.방법 2: GitHub — 다른 사람이 한 줄 URL로 설치
커뮤니티에서 가장 흔한 방식입니다: 빌드 산출물을 만들어 GitHub Release에 업로드하고, 다른 사람이 한 줄 URL로 설치. CH 12에서 설치한 DSH Skill & MCP Panel이 바로 이 방식으로 배포된 것이었습니다.
세 단계:
- 패키징: 플러그인 디렉터리에서
pnpm pack,your-plugin-0.0.1.tgz생성. - 업로드: 저장소를 GitHub에 푸시한 뒤, 저장소 페이지에서 Release를 생성하고(버전 번호
v0.0.1작성).tgz업로드. - 설치 주소 전달: 다른 사람이 다음 주소로 설치:
dsh plugin --profile web add https://github.com/your-username/repo-name/releases/download/v0.0.1/your-plugin-0.0.1.tgz설치되는 것은 빌드 산출물이며, allowBuilds 승인이 필요 없고, npm에서 설치하는 것과 동일한 정도로 쉽습니다. "항상 최신을 가리키는" 주소를 고정하려면, download/v0.0.1/...를 releases/latest/download/your-plugin.tgz로 바꾸면 됩니다(파일명에 버전 번호 포함하지 않음).
주의: 이 방식으로 진행되는 플러그인은 일반적으로 lib/이 git에 들어 있지 않습니다 — 저장소에는 소스 코드만 들어 있으며, 발행 전에 로컬에서 빌드하고 pnpm pack으로 tarball를 만든 뒤 Release에 업로드합니다.
고급: GitHub Actions로 자동 빌드 및 발행
수동 패키징, Release 생성 및 파일 업로드를 한 번 하는 것은 괜찮지만, 버전이 많아지면 번거로워집니다. GitHub Actions에게 맡기세요: v0.0.1 태그를 푸시하면 Actions가 자동으로 빌드 → pnpm pack → Release 생성 → tarball 업로드를 수행합니다. 그 뒤로는 새 태그를 푸시하기만 하면 새 버전이 만들어지고, 나머지는 모두 자동으로 진행됩니다.
전형적인 workflow는 저장소의 .github/workflows/release.yml에 들어갑니다: 트리거는 push: tags: ['v*'], 단계 순서는 checkout 코드 → Node 설치 → pnpm install → pnpm build → pnpm pack, softprops/action-gh-release로 Release를 생성하고 생성된 .tgz를 첨부 파일로 업로드. 한 번 설정해 두면, 버전마다 파일을 수동으로 업로드할 필요가 없습니다.
발행을 dsh에게 맡길 수도 있습니다
패키징, 저장소 푸시, Release 생성 — 이 반복 작업은 dsh에게 맡기면 됩니다. Web UI의 입력창에 다음을 보냅니다:
현재 워크스페이스의 플러그인을 GitHub에 발행하고 v0.0.1을 릴리스해 줘. GitHub Actions를 사용해 dsh 공식 명세에 따라 자동 빌드 및 발행을 수행하고, 마지막에 다른 사람이 어떤 주소로 설치할 수 있는지 알려 줘.dsh가 문서를 직접 읽고, 명령을 직접 실행하며, git과 Release를 직접 처리합니다. 저장소 푸시, Release 생성과 같이 경계를 넘는 작업을 수행할 때는 권한 정책에 따라 확인만 해주시고, 마지막에 설치 주소가 올바른지 검증하면 됩니다.
방법 3: npm에 발행 — 다른 사람은 패키지명만 입력
플러그인을 npm에 발행하면, 다른 사람의 설치는 가장 간결해집니다: dsh plugin --profile web add your-plugin.
네 단계:
- npm 가입 및 로그인: npm 사이트에서 계정을 등록하고(무료),
npm login실행(사용자명, 비밀번호, 이메일을 물음). - 빌드:
lib/가 빌드 산출물임을 확인. 소스 형태의 플러그인은 발행 전에pnpm build가 필요합니다 — npm은 미리 빌드된 코드를 설치하므로, 빌드 없이 발행하면 다른 사람이 빈 패키지를 받게 됩니다. - 발행: 플러그인 디렉터리에서
pnpm publish실행. - 검증: 깨끗한 profile로 전환해
dsh plugin --profile test add your-plugin로 설치 및 실행 확인.
발행 후: dsh-plugin 토픽 달기
방법에 관계없이, GitHub 저장소의 Topics에 dsh-plugin을 추가하세요 — 공식 팀이 명시적으로 권장하는 사항이며, 다른 사람이 본인의 플러그인을 더 쉽게 찾을 수 있습니다. npm 패키지의 keywords에도 dsh-plugin을 포함시켜 이중으로 대비하는 것을 잊지 마세요.
자주 겪는 함정
| 문제 | 현상 | 대응 |
|---|---|---|
| 설치했는데 효과 없음 | bundle 멤버 변경 후 재시작하지 않음 | 설치 후 profile을 재시작하고 테스트 |
| 다른 사람이 설치 후 적재 실패 | files에 lib/가 빠져 소스만 배송됨 | 빌드 산출물 디렉터리를 files에 추가하고 재패키징 |
| 버전 번호 중복 | 같은 버전으로 publish는 npm에서 영구 거절 | 다른 버전으로 바꾼 뒤 발행 |
| 패키지명 점유 | npm에 같은 이름이 이미 존재 | 무관한 패키지명을 선택 |
| 설치되었으나 활성화되지 않음 | 패키지가 dsh.bundle을 선언하지 않음 | "dsh":{"bundle":{...}} 추가, 그렇지 않으면 일반 의존성에 불과해 마운트되지 않음 |
이 장에서 배운 것
아래 항목들을 직접 해낼 수 있으면 합격입니다:
- [ ] bundle은 "본인이 배포하는 것", profile은 "사용자가 시작하는 것"이며, 두 manifest가 다르다는 것을 안다
- [ ] 발행 가능한 플러그인의 올바른 package.json을 작성할 수 있다: name / version / files / keywords / license / dsh.bundle, UI가 있다면 dsh.client도
- [ ] 세 가지 배포 방법의 적절한 시나리오를 안다: 로컬/tarball 자체 검증, GitHub Release tarball(주류 원클릭 설치, Actions 자동 발행 지원), npm 발행
- [ ] 발행 전 자체 검증:
pnpm pack→ 임시 profileadd→--dump-config확인 → 재시작 후 검증 - [ ] 패키징, 자체 검증, GitHub 발행을 dsh에게 맡길 수 있으며, 단계별로 손수 하지 않아도 됨을 안다
- [ ] 발행 후 GitHub 저장소에
dsh-plugin토픽을 달고, npm 패키지 keywords에dsh-plugin을 포함시켜야 함을 안다 - [ ] 흔한 함정을 피할 수 있다:
files에lib/누락, bundle 변경 후 재시작 누락, 패키지의dsh.bundle선언 누락
