샌드박스 플러그인이 작동하면 EmDash 마켓플레이스에 게시하여 다른 사이트가 관리 대시보드에서 한 번의 클릭으로 설치할 수 있습니다. 게시 흐름은 샌드박스 전용입니다. 네이티브 플러그인은 npm을 통해 배포되며 마켓플레이스 tarball에 번들되지 않습니다.
전제 조건
게시하기 전에 플러그인이 다음을 확인하세요:
"."익스포트(디스크립터)와"./sandbox"익스포트(런타임 진입점) 모두를 가진package.json이 있습니다.- 디스크립터에서
format: "standard"를 사용합니다. - 고유한
id와 유효한 semverversion이 있습니다. - 디스크립터에
capabilities와allowedHosts를 정확하게 선언합니다.
번들 형식
게시된 플러그인은 다음을 포함하는 .tar.gz tarball로 배포됩니다:
| 파일 | 필수 | 설명 |
|---|---|---|
manifest.json | 예 | 디스크립터 및 샌드박스 진입점에서 추출된 플러그인 메타데이터 |
backend.js | 예 | 번들된 샌드박스 코드(자체 포함 ES 모듈) |
admin.js | 아니오 | 번들된 관리 UI 코드(Block Kit 상호작용이 JS를 제공하는 경우에만) |
README.md | 아니오 | 플러그인 문서 |
icon.png | 아니오 | 플러그인 아이콘(256×256 PNG) |
screenshots/ | 아니오 | 최대 5개의 스크린샷(PNG/JPEG, 최대 1920×1080) |
manifest.json은 자동으로 생성됩니다. 플러그인 ID, 버전, capabilities, 허용된 호스트, 훅 이름, 라우트 이름 및 관리 구성이 포함되지만 실행 가능한 코드는 포함되지 않습니다.
번들 빌드
cd packages/plugins/my-plugin
emdash plugin bundle
이것은 다음을 수행합니다:
- 진입점을 찾기 위해
package.json을 읽습니다. - ID, 버전, capabilities 및 관리 구성을 추출하기 위해 디스크립터 진입점을 빌드합니다.
"./sandbox"익스포트에서backend.js를 번들합니다 — 최소화, 트리 쉐이킹, 완전히 자체 포함."./admin"익스포트가 존재하면admin.js를 번들합니다.- 자산(README, 아이콘, 스크린샷)을 수집합니다.
- 번들을 검증합니다(크기 제한,
backend.js에 Node.js 내장 모듈 없음, capability 체크). {id}-{version}.tar.gz를dist/에 작성합니다.
진입점 해결
번들 명령은 package.json 익스포트를 통해 코드를 찾습니다:
{
"exports": {
".": { "import": "./dist/index.mjs" },
"./sandbox": { "import": "./dist/sandbox-entry.mjs" },
"./admin": { "import": "./dist/admin.mjs" }
}
}
| 익스포트 | 목적 | 빌드 방식 |
|---|---|---|
"." | 디스크립터 — 매니페스트를 추출하는 데 사용 | Externals: emdash, @emdash-cms/* |
"./sandbox" | 샌드박스에서 실행되는 런타임 코드(hooks, routes) | 완전히 자체 포함(externals 없음) |
"./admin" | 관리 UI 컴포넌트(제공하는 경우에만) | 완전히 자체 포함 |
"./sandbox"가 없으면 명령은 대체로 src/sandbox-entry.ts를 찾습니다. 번들러는 dist 경로를 자동으로 소스에 매핑합니다 — "." 익스포트가 ./dist/index.mjs를 가리키는 경우 src/index.ts를 찾아서 빌드합니다.
옵션
emdash plugin bundle [--dir <path>] [--outDir <path>]
| 플래그 | 기본값 | 설명 |
|---|---|---|
--dir | 현재 디렉터리 | 플러그인 소스 디렉터리 |
--outDir, -o | dist | tarball 출력 디렉터리 |
검증
번들 명령은 다음을 확인합니다:
- 크기 제한 — 전체 번들은 5MB 미만이어야 합니다.
backend.js에 Node.js 내장 모듈 없음 — 샌드박스 코드는fs,path,child_process등을 임포트할 수 없습니다. 웹 API로 교체하거나 로직을 네이티브 플러그인으로 이동하세요.- Capability 화이트리스트 — 선언된 capabilities는 알려진 세트에 있어야 합니다(오타는 실패합니다).
- 더 이상 사용되지 않는 capability 이름은 여기서 경고를 트리거하고 게시 시 하드 실패를 발생시킵니다.
- **
allowedHosts없는network:request**는 경고를 트리거합니다(호스트가 런타임에 운영자에 의해 구성되는 경우network:request:unrestricted를 고려하거나 호스트를 명시적으로 나열하세요). - 아이콘 크기 —
icon.png는 256×256이어야 합니다(틀린 경우 경고하지만 여전히 포함합니다). - 스크린샷 제한 — 최대 5개, 최대 1920×1080.
게시
emdash plugin publish
이것은 dist/에서 가장 최근의 .tar.gz를 찾아 업로드합니다. tarball을 명시적으로 지정하거나 게시하기 전에 빌드하려면:
# 명시적 tarball 경로
emdash plugin publish --tarball dist/my-plugin-1.0.0.tar.gz
# 먼저 빌드한 다음 게시
emdash plugin publish --build
인증
처음 게시할 때 CLI는 GitHub를 통해 인증합니다:
- CLI가 브라우저에서 GitHub의 장치 인증 페이지를 엽니다.
- 터미널에 표시된 코드를 입력합니다.
- GitHub가 액세스 토큰을 발급합니다.
- CLI가 이를 마켓플레이스 JWT로 교환합니다(
~/.config/emdash/auth.json에 저장됨).
토큰은 30일 동안 지속됩니다. 만료된 후 다음 게시 시 다시 인증하라는 메시지가 표시됩니다.
인증을 별도로 관리할 수 있습니다:
emdash plugin login # 게시 없이 로그인
emdash plugin logout # 저장된 토큰 지우기
최초 등록
플러그인 ID가 아직 마켓플레이스에 알려지지 않은 경우 emdash plugin publish는 첫 번째 버전을 업로드하기 전에 자동으로 등록합니다.
버전 요구 사항
게시된 각 버전은 이전 버전보다 높은 semver를 가져야 합니다. 기존 버전을 덮어쓰거나 다시 게시할 수 없습니다 — 다시 게시하기 전에 package.json과 디스크립터 모두에서 버전을 올리세요.
보안 감사
게시된 각 버전은 자동화된 보안 감사를 거칩니다. 감사는 backend.js와 admin.js를 다음에 대해 스캔합니다:
- 데이터 유출 패턴
- 설정을 통한 자격 증명 수집
- 난독화된 코드
- 리소스 남용(암호화폐 채굴 등)
- 의심스러운 네트워크 활동
감사는 pass, warn 또는 fail의 판정을 생성하며 플러그인의 마켓플레이스 목록에 표시됩니다. 마켓플레이스의 시행 수준에 따라 fail 판정은 게시를 완전히 차단할 수 있습니다.
옵션
emdash plugin publish [--tarball <path>] [--build] [--dir <path>] [--registry <url>]
| 플래그 | 기본값 | 설명 |
|---|---|---|
--tarball | dist/의 최신 .tar.gz | 명시적 tarball 경로 |
--build | false | 게시하기 전에 emdash plugin bundle 실행 |
--dir | 현재 디렉터리 | 플러그인 디렉터리(--build와 함께 사용) |
--registry | https://marketplace.emdashcms.com | 마켓플레이스 URL |
전체 워크플로
일반적인 게시 주기:
# 1. 변경 사항 적용
# 2. src/index.ts 및 package.json에서 버전 올리기
# 3. 번들 및 게시
emdash plugin publish --build
먼저 번들을 검사하려면:
emdash plugin bundle
tar tzf dist/my-plugin-1.1.0.tar.gz
emdash plugin publish