Skip to content

CH 17 · 플러그인 설치

전체 글자 수약 6,370 자예상 소요 시간약 20분선행CH 08 (플러그인 트리), CH 12 (MCP 연동)난이도재현 가능

본 장 목표

CH 12에서 이미 세 개의 플러그인을 설치하셨습니다 — dsh-mcp-client, dshmarket, dsh-skill-mcp-panel — 다만 그때는 "그때그때 설치하고, 작동하면 됐지" 식이었기에 세 가지 설치 방법에 대해서는 자세히 다루지 않았습니다. 이 장에서는 플러그인 설치를 체계적으로 다룹니다. 플러그인이 어디에서 오는지, 어디에 설치되는지, 설치 방법에는 어떤 것들이 있는지, 어떻게 관리하는지, 설치 후 어떻게 확인하는지 — 그리고 마지막에는 직접 한 번 실습으로 설치해 봅니다. 게다가 직접 dsh에게 설치를 맡기는 것까지 합니다.

먼저 한 문장만 기억해 두세요: 플러그인 설치 = 어떤 profile에 npm 의존성을 추가하는 것. dsh는 "모든 것이 플러그인"입니다(CH 08에서 다룸), 그러나 플러그인의 "설치" 자체는 표준 패키지 관리 방식을 따릅니다. 설치를 이해하면, CH 18에서 첫 플러그인을 직접 작성합니다.

먼저 본인 설치 현황 살펴보기

터미널을 열고, 먼저 dsh 본체의 버전을 확인합니다:

powershell
dsh --version

제 출력입니다:

text
0.1.1-rc.2

이어서 web profile에 이미 어떤 플러그인들이 설치되어 있는지 확인합니다:

powershell
dsh plugin --profile web list

제 출력입니다(CH 12에서 설치한 결과 그대로):

text
Legend: production dependency, optional only, dev only

dsh-profile-web C:\Users\mortal\.dsh\profiles\web (PRIVATE)

│   dependencies:
├── @deepseek-ai/dsh-mcp-client@0.0.1-rc.1
├── dsh-skill-mcp-panel@2.0.1
└── dshmarket@1.40.0

3 packages

이 세 줄이 정확히 세 가지 설치 방법에 각각 대응됩니다: mcp-client명령행으로 설치한 것이고, dshmarket명령행으로 설치한 마켓 본체이며, dsh-skill-mcp-panel은 마켓에서 원클릭 설치한 것입니다 — 그리고 이 둘이 별다른 설정 없이 곧바로 설정 트리에 들어가서 적용되는 이유는 세 번째 메커니즘인 bundle 자동 마운트 덕분입니다. 아래에서 하나씩 설명합니다.

플러그인은 어디에서 오는가: 네 가지 출처

플러그인은 본질적으로 npm 패키지이며, 출처는 다음과 같습니다:

출처표기사용 시점
npm 패키지@deepseek-ai/dsh-mcp-client가장 흔함. 공식 패키지는 @deepseek-ai/ 접두사를 달고, 커뮤니티 패키지는 자체 scope 사용
GitHub 소스github:owner/repo어떤 저장소의 main 브랜치를 설치하고 싶을 때, npm에 등록되지 않았을 때
로컬 디렉터리. 또는 file:../plugin본인이 플러그인을 개발 중일 때, 로컬 checkout을 그대로 설치하여 수정·테스트
tarball / Release 산출물.tgz의 URL 또는 로컬 경로작성자가 빌드 산출물만 배포할 때, 예: GitHub Release의 첨부 파일

CH 12에서 설치한 **dsh-market(플러그인 마켓)**은 새로운 출처가 아니라 그래픽 진입점입니다. 설치 후에는 설정에서 커뮤니티 플러그인을 탐색·검색·원클릭 설치할 수 있고, 내부적으로는 위에서 언급한 출처들을 호출합니다.

어디에 설치되는가: Profile 레벨, profile을 따름

dsh plugin특정 profile의 플러그인을 관리하므로, 명령에는 반드시 --profile <이름>을 붙여 어떤 환경에 설치할지 지정해야 합니다. 설치된 패키지는 다음 위치에 들어갑니다:

text
$DSH_HOME/profiles/<이름>/node_modules

Windows에서는 C:\Users\<사용자 이름>\.dsh\profiles\web\node_modules이며, pnpm이 관리하고 profile의 package.json에도 함께 기록됩니다.

쉽게 혼동하는 부분 하나를 짚고 가겠습니다 — 전역과 Profile의 차이:

  • dsh 본체는 전역 설치됩니다(이전의 npm install -g @deepseek-ai/dsh), 모든 profile이 동일한 dsh를 공유합니다.
  • 플러그인은 기본적으로 profile별입니다: dsh plugin --profile web add xxx는 web에서만 적용됩니다. headless에서도 사용하려면 headless에도 별도로 설치해야 합니다.
  • 머신 레벨 설정은 또 다른 계층입니다: $DSH_HOME/cordis.patch.yml은 모든 profile이 공유하며(공식 명칭은 "machine-local preferences"), 게다가 profile 자체의 cordis.patch.yml보다 우선순위가 더 높습니다 — 모든 환경에 동일한 변경을 적용하고 싶다면 여기에 작성하세요.

이 파일들이 각각 어디에 있는지 먼저 정리하고, 헷갈리지 않도록 합시다. profile 레벨의 파일은 C:\Users\<사용자 이름>\.dsh\profiles\web\cordis.patch.yml이며(CH 12에서 MCP 서버 설정을 수정한 바로 그 파일입니다), 머신 레벨의 파일은 C:\Users\<사용자 이름>\.dsh\cordis.patch.yml입니다 — 이 파일은 기본적으로 존재하지 않으며, 사용자가 직접 설정을 작성해야 만들어지고, dsh는 시작할 때 이 파일을 읽으며 파일이 없으면 건너뜁니다. 따라서 "내가 작성한 설정이 정말 머신 레벨인지" 확인하려면, .dsh 루트 디렉터리에 있는지 살펴보면 됩니다. profiles\<이름>\ 아래에 있다면 그것은 profile 레벨입니다.

  • 공식 내장 bundle(@deepseek-ai/dsh-base, @deepseek-ai/dsh-web-app 등)은 dsh와 함께 제공되며 전역 설치에서 비롯됩니다. 본인이 직접 추가한 플러그인은 profile 자체의 node_modules에 설치됩니다.

한 문장으로 정리: dsh 본체는 전역, 플러그인은 profile을 따르고, 머신 레벨 패치는 사이트 전체에 적용.

세 가지 설치 방법

① 명령행 dsh plugin: 가장 근본적인 방법

이것이 가장 근본적인 설치 방법입니다. dsh plugin --profile <이름>은 뒤따르는 인자를 있는 그대로 pnpm에 전달하므로, add, remove, update, why, list 같은 pnpm 동사들이 모두 사용 가능하고, 표기 역시 npm 패키지 관리 표기를 그대로 따릅니다:

powershell
dsh plugin --profile web add @deepseek-ai/dsh-mcp-client

공식 문서의 전형적인 예시로는 두 개의 subagent 플러그인 설치(선택적 bundle)가 있습니다:

powershell
dsh plugin --profile web add @deepseek-ai/dsh-subagent-codex @deepseek-ai/dsh-subagent-claude-code
dsh plugin --profile web remove @deepseek-ai/dsh-subagent-codex

본인이 개발한 플러그인을 로컬 디렉터리에서 설치하는 것도 바로 이 방법을 사용합니다 — 플러그인 소스 디렉터리에서 dsh plugin --profile web add .를 실행하면 현재 checkout이 그대로 설치됩니다(상대 경로는 명령을 실행한 디렉터리를 기준으로 하며, profile 디렉터리가 아닙니다).

② 플러그인 마켓 dsh-market: 가장 쉬운 방법

그래픽 설치 방법입니다. 먼저 마켓 본체를 설치합니다:

powershell
dsh plugin --profile web add dshmarket

설치 후 dsh를 재시작합니다(bundle 변경은 재시작이 필요하며, 자세한 내용은 아래에서 설명), 설정에 새로운 "플러그인 마켓"이 나타납니다. 카테고리별로 탐색하고, 검색하고, 커뮤니티 플러그인을 원클릭으로 설치할 수 있습니다. 마켓을 통해 설치한 대부분의 플러그인은 페이지를 새로 고치기만 하면 적용되어 dsh를 재시작할 필요가 없습니다. 일부 host 레벨 플러그인은 "재시작 필요"를 안내하는데, 안내에 따르시면 됩니다. CH 12에서 설치한 dsh-skill-mcp-panel은 마켓에서 검색해 원클릭으로 설치한 것이었습니다.

설정 → 플러그인 마켓: 발견 / 주제 / 설치됨 탭, 카테고리 + 검색 상자 + 설치 버튼이 있는 플러그인 카드

③ Bundle 자동 마운트: 설치와 동시에 설정 트리에 진입

반드시 한번쯤 의문을 가져보셨을 현상부터 짚고 가겠습니다: 왜 mcp-client는 설치 후 서버 설정을 위해 cordis.patch.yml에 수동으로 insert를 작성해야 하는 반면, dshmarketdsh-skill-mcp-panel은 설치 후 별다른 설정 없이 적용될까요? 답은 플러그인 자체의 package.json에 있습니다 — 차이는 dsh.bundle 선언 여부입니다. "설치 즉시 설정 트리에 자동 진입"하려면, 플러그인이 자신의 manifest에서 다음 필드를 선언해야 합니다:

json
{
  "dsh": {
    "bundle": {
      "patch": "./cordis.patch.yml"
    }
  }
}

dsh는 dsh plugin 실행이 성공할 때마다마다 bundle 목록을 재조정합니다. dependencies에 포함된 패키지 중 dsh.bundle 선언이 있는 것은 해당 profile의 bundle 레이어(설정 트리의 맨 아래에 있는 기본 레이어, CH 08에서 다룸)에 자동으로 추가되며, 수동으로 insert할 필요가 없습니다.

실례로, 선언이 있는 두 플러그인의 package.json을 살펴봅니다. dshmarket@1.40.0:

json
"dsh": {
  "bundle": { "patch": "./cordis.patch.yml" },
  "client": { "inject": ["@deepseek-ai/dsh-client-connection", "..."], "platform": "web" }
}

dsh-skill-mcp-panel@2.0.1:

json
"dsh": {
  "client": { "platform": "web", "inject": ["@deepseek-ai/dsh-client-runtime", "..."] },
  "bundle": { "patch": "./cordis.patch.yml" }
}

둘 다 bundle.patch 선언이 있으므로, 둘 다 profile manifest의 bundle 목록에 자동 등록됩니다. web profile의 package.json을 열어 보면, bundle 레이어는 다음과 같이 구성됩니다:

json
"dsh": {
  "profile": {
    "bundles": [
      "@deepseek-ai/dsh-base",
      "@deepseek-ai/dsh-web-app",
      "dsh-skill-mcp-panel",
      "dshmarket"
    ]
  }
}

앞의 두 개는 공식 내장 bundle(전역 dsh 설치와 함께 제공)이고, 뒤의 두 개는 본인이 설치한 후 자동 마운트된 것입니다. 그렇다면 dsh-mcp-client는 어떨까요? 이 플러그인은 dsh.bundle 선언이 없으므로, 일반적인 의존성에 불과합니다 — profile의 package.json dependencies에는 나타나지만 bundles 목록에는 들어 있지 않습니다. 비유하자면: bundle 플러그인은 "설명서가 동봉된, 꺼내면 바로 쓸 수 있는 도구"이고, 일반 의존성은 "도구만 있고 설명서는 없는" 상태 — 물건은 도착했지만 dsh가 능력을 자동으로 적재하지는 않으며, 사용자가 직접 설정해야 합니다.

dsh-mcp-client가 바로 후자입니다: 이는 "MCP 서버에 연결하는 엔진"이며, 연결하는 법은 알지만 어디에 연결할지는 모릅니다. 사용자가 직접 어떤 서버에 연결할지, 주소는 무엇인지, 키는 어떻게 전달하는지를 알려주어야 합니다 — 이 행위가 바로 cordis.patch.ymlinsert를 작성하는 것입니다(서버 설정 한 줄을 설정 트리에 삽입). CH 12에서 작성하셨던 Firecrawl 설정이 바로 그러한 insert였습니다.

또 하나 짚어둘 점: 이 두 플러그인은 dsh.client 선언도 함께 가지고 있습니다(platform: web + client 플러그인 주입 목록). 그래서 이 두 플러그인이 Web UI 설정에 인터페이스를 추가할 수 있는 것입니다(플러그인 마켓, MCP 관리) — bundle이기도 하고(설정 트리에 진입) client 주입도 선언하는(인터페이스에 진입) 셈입니다.

반드시 기억할 경계: bundle 멤버(bundles 목록에 들어 있는 것)의 변경 이후에는 반드시 profile을 재시작해야 적용됩니다 — 실행 중인 profile은 시작 시점의 bundle 집합을 그대로 유지하며, 새로 설치한 bundle은 다음 시작 시에만 적재됩니다. 여기서 "재시작"의 의미는 단지 자동 적재를 위한 것일 뿐, 무언가를 설정해야 한다는 뜻이 아닙니다 — bundle 플러그인이 적재되면 곧바로 사용할 수 있으며, 설정을 만질 필요는 없습니다. 일반적인 cordis.patch.yml 수정은 핫 리로드로 처리되므로 재시작이 필요 없습니다. 하지만 bundle의 add/remove/update는 재시작이 불가피합니다. CH 12에서 dshmarket 설치 후 재시작하셨던 이유가 바로 이 자동 적재를 위해서였습니다.

관리 명령어 모음표

명령어효과
dsh plugin --profile web list해당 profile에 설치된 항목 나열(pnpm list와 동일)
dsh plugin --profile web add <출처>설치, 출처는 위의 네 가지 참조
dsh plugin --profile web remove <패키지>제거
dsh plugin --profile web update <패키지>최신 버전으로 갱신(bundle 선언이 있는 것은 새 선언과 재조정)
dsh plugin --profile web why <패키지>해당 패키지가 설치된 이유 확인(누가 의존하는지)

설치 후 어떻게 확인하나요? 두 가지 방법이 있습니다:

  • 의존성과 bundle 귀속 확인: dsh plugin --profile web list로 의존성 확인, bundle 레이어에 들어갔는지 보려면 profile의 package.json(위의 dsh.profile.bundles)을 직접 살펴봅니다.
  • 설정 트리에 실제로 마운트되었는지 확인: dsh --profile web --dump-config로 전체 설정 트리를 출력하고 플러그인명을 검색합니다. bundle 기본 레이어만 보고 싶다면 dsh --profile web --dump-default-config를 사용합니다.

실제로 쓸모 있는 커뮤니티 플러그인 세 개 설치하기

앞서 설치한 플러그인은 메커니즘 설명을 위한 것이었고, 그 과정에서도 실제로 필요한 것들이었습니다 — dsh는 원래 그렇습니다. 원하는 것을 설치하고, 모든 것이 플러그인입니다. 이제 "설치 즉시 사용성이 좋아지는" 커뮤니티 플러그인 세 개를 설치합니다. GitHub 소스와 npm에서 가져옵니다. 직접 명령을 입력할 필요 없이, dsh에게 맡기면 됩니다.

dsh-theme: Web UI 스킨 변경하기

독립형 테마 플러그인입니다. 설치 후 설정에 새로운 "외관(Appearance)" 항목이 추가됩니다:

  • 세 가지 외관 모드: 라이트 / 다크 / 시스템 따르기
  • 큐레이션된 15종 테마, 그중 5종은 읽기용 테마, 1종은 코드용 Carbon Code 테마
  • 각 테마는 색상 단계, UI 폰트, 코드 폰트, 글자 크기를 통합된 설정으로 묶어 한 번에 전환 가능
  • 강조 색상, 배경, 전경, 표면, 사이드바 색상을 실시간으로 개별 조정 가능
  • 설정은 브라우저 로컬에 저장되어 새로 고침해도 유지(브라우저·profile 간 동기화는 안 됨)

dsh에게 설치를 맡기려면 입력창에 다음과 같이 보냅니다:

text
dsh-theme 플러그인을 web profile에 설치하고 잘 작동하는지 확인해 줘. GitHub에 oil-oil/dsh-theme 저장소에 있어.

소스: oil-oil/dsh-theme. 설치 후 web profile을 재시작하면, 설정 → 외관에서 테마를 전환할 수 있으며, 모습은 다음과 같습니다:

dsh-theme 설치 후 설정 → 외관 페이지, 테마 전환, 강조 색상/배경/글자 색 조정

dsh-oil-sticky-prompt: 스크롤 중 최신 사용자 메시지를 상단에 고정하기

긴 응답을 스크롤할 때, 최신 사용자 메시지가 압축된 풀폭 바로 대화 상단에 고정되며, 클릭하면 원래 위치로 돌아갑니다:

  • 단일 고정 바, 여러 토픽이 있어도 충돌하지 않음
  • 원래의 줄바꿈은 공백으로 평탄화되고, 최대 두 줄로 표시
  • 메시지 자체를 수정하지 않으며, 세션 로그에도 손대지 않고, 설정도 저장하지 않음

dsh에게 설치를 맡기려면 입력창에 다음과 같이 보냅니다:

text
dsh-oil-sticky-prompt 플러그인을 web profile에 설치하고 잘 작동하는지 확인해 줘. GitHub에 oil-oil/dsh-oil-sticky-prompt 저장소에 있어.

소스: oil-oil/dsh-oil-sticky-prompt. 설치 후 dsh를 재시작합니다. 아래는 dsh가 실제로 설치해 준 모습입니다 — Peer dependency 경고는 예상된 동작이며, 다음에 web profile을 재시작할 때 적용된다고 설명합니다:

dsh가 실제로 dsh-oil-sticky-prompt를 설치하는 대화: Peer dependency 경고 설명, 적용 방식 설명

dsh-better-sidebar: 사이드바를 본격 워크벤치로 바꾸기

기능이 가장 풍부한 플러그인으로, 오른쪽 사이드바를 "워크벤치"로 끌어올립니다. 그 설계 사상은 Codex 같은 AI 코딩 도구의 사이드바와 같은 계열입니다 — 파일, 터미널, Git을 Agent 옆으로 옮겨놓고, 작업하는 모습을 지켜볼 수 있게 합니다:

  • 파일 워크벤치: 디렉터리 트리 + 코드 에디터, 이미지 / Markdown / HTML / PDF / Office 인라인 미리보기
  • 임베디드 브라우저: 여러 웹페이지 탭, 샌드박스 iframe에서 실행
  • 실제 터미널: xterm + node-pty로 실제 셸을 실행, 연결 끊김 시 재연결, 터미널 도구를 모델에 주입하는 옵션
  • Git 패널: 실제 diff, 히스토리, 우클릭 stage / commit / revert
  • 백그라운드 작업 페이지: subagent 토폴로지와 백그라운드 작업 확인(종료 코드 / 실시간 출력 / 강제 종료)
  • 오른쪽 사이드바 + 하단 패널의 듀얼 워크벤치, 레이아웃은 세션별로 기억

dsh에게 설치를 맡기려면 입력창에 다음과 같이 보냅니다:

text
dsh-better-sidebar 플러그인을 web profile에 설치하고 잘 작동하는지 확인해 줘. GitHub에 omdsh-dev/DSH-better-sidebar 저장소에 있어 (npm 패키지 이름은 dsh-better-sidebar).

소스: omdsh-dev/DSH-better-sidebar. 설치 후 dsh를 재시작한 다음 브라우저를 하드 새로고침해야 사이드바가 보입니다(bundle 멤버라서 재시작 시에만 적재). 우측 파일 브라우저 + 하단 터미널이 함께 나타납니다:

dsh-better-sidebar: 우측 파일 브라우저 + 하단 터미널, Codex 스타일의 사이드바 워크벤치

이 세 가지 모두 bundle 선언이 있어 설치 시 자동 마운트됩니다(③의 메커니즘). GitHub 소스로 처음 설치하는 두 플러그인은 pnpm의 allowBuilds에 막힐 수 있는데, 그 부분은 "자주 겪는 함정"에서 다룹니다.

자주 겪는 함정

문제현상대응
설치했는데 UI 변화가 없음?bundle 멤버를 설치한 경우 실행 중인 profile은 자동 리로드되지 않음dsh를 재시작한 뒤 설정 다시 확인
Git 소스 플러그인 첫 add에서 allowBuilds 오류?pnpm ≥10은 기본적으로 소스 패키지가 prepare 빌드 스크립트를 실행하지 못하게 막음오류에 표시된 안내에 따라 allow 키를 profile 디렉터리의 pnpm-workspace.yaml에 복사한 뒤 add 재실행
dsh-better-sidebar 설치 시 "Ignored build scripts"가 보고됨?pnpm 11이 node-pty 같은 네이티브 모듈의 빌드 스크립트를 차단profile 디렉터리(C:\Users\<사용자 이름>\.dsh\profiles\web)에서 pnpm approve-builds --all 실행 후 하드 새로고침
설치 후 사이드바가 두 개 나타남?이전에 수동으로 마운트한 라인이 자동 bundle과 이중 마운트됨cordis.patch.yml에서 기존의 - insert: ... better-sidebar ... 수동 마운트 라인 제거
잘못된 환경에 설치함?--profile로 설치 대상이 결정됨명령의 profile 이름이 원하는 것인지 확인(web / headless 등)
설치했는데 오류 없이 적용되지 않음?일반 의존성(dsh.bundle 선언 없음)을 설치했을 수 있음이는 단순히 "패키지 도착" 상태이며, 능력을 연결하려면 cordis.patch.yml에 직접 insert해야 함(mcp-client가 대표적 사례)

이 장에서 배운 것

아래 항목들을 직접 해낼 수 있으면 합격입니다:

  • [ ] 네 가지 플러그인 출처(npm / GitHub / 로컬 디렉터리 / tarball)를 말할 수 있고, 플러그인 마켓은 출처가 아니라 그래픽 진입점임을 설명할 수 있다
  • [ ] dsh plugin --profile <이름>이 특정 profile의 플러그인을 관리하며, 그 profile의 node_modules에 설치된다는 것을 안다
  • [ ] 구분할 수 있다: dsh 본체는 전역 설치, 플러그인은 profile별, $DSH_HOME/cordis.patch.yml은 머신 레벨이며 사이트 전체에 적용
  • [ ] 세 가지 설치 방법을 안다: 명령행 add / 마켓 원클릭 설치 / dsh.bundle 선언이 있는 의존성의 자동 마운트
  • [ ] 세 가지 커뮤니티 플러그인의 용도(dsh-theme 스킨 / dsh-oil-sticky-prompt 고정 프롬프트 바 / dsh-better-sidebar 사이드바 워크벤치)를 말할 수 있고, 직접 설치해 본다
  • [ ] bundle 멤버의 변경은 profile 재시작이 필요하다는 것을 알고, 일반 patch 수정은 핫 리로드로 처리됨을 안다
  • [ ] list / remove / update로 플러그인을 관리하고, --dump-config로 설정 트리에 마운트되었는지 확인한다

Open Source · MIT · Community Driven